簡體   English   中英

兩次讀取讀取對象會導致“ IndexError:列表索引超出范圍”

[英]Reading cread object twice causes 'IndexError: list index out of range'

兩次讀取csv閱讀器對象時,出現錯誤“ IndexError:列表索引超出范圍”。 現在,我正在通過迭代對象來創建字典,但是在嘗試創建類似列表時失敗。 為了簡潔起見,其他代碼塊被省略,以下是相關代碼:

# Parse csv files for samples, creating a dictionary of key, value pairs and multiple lists.
with open('genes.csv') as f:
    cread = csv.reader(f, delimiter = '\t')
    sample_1_dict = {i: float(j) for i, j in cread}
    sample_1_list = [x for x in sample_1_dict.items()]
    sample_1_genes_sorted = sorted(sample_1_list, key=lambda expvalues: expvalues[0])
    sample_1_values_sorted = sorted(sample_1_list, key=lambda expvalues: expvalues[1])
    sample_1_genes = [i for i, j in sample_1_values_sorted]
    sample_1_values = [j for i, j in sample_1_values_sorted]
    sample_1_graph_un = [float(j) for i, j in cread]

...

sample_values_list = [i for i in sample_1_graph_un, sample_2_graph_un, sample_3_graph_un, sample_4_graph_un, sample_5_graph_un, sample_6_graph_un]

sample_graph_list_un = [[i for i in sample_value] for sample_value in sample_values_list]

colors = 'bgrcmy'
alphas = ['0.5', '0.5', '0.5', '0.5', '0.5', '0.5']
labels = ['278', '470', '543', '5934', '6102', '17163']

for graph, color, alpha, label in zip(sample_graph_list_un, colors, alphas, labels):
    plt.hist(graph, bins = 21, histtype = 'stepfilled', normed = True, color = color, alpha = float(alpha), label=label)

我要重新打開csv文件,並且以下代碼可以正常工作:

# Parse csv files for samples, creating a dictionary of key, value pairs and multiple lists.
with open('genes.csv') as f:
    cread = csv.reader(f, delimiter = '\t')
    sample_1_dict = {i: float(j) for i, j in cread}
    sample_1_list = [x for x in sample_1_dict.items()]
    sample_1_genes_sorted = sorted(sample_1_list, key=lambda expvalues: expvalues[0])
    sample_1_values_sorted = sorted(sample_1_list, key=lambda expvalues: expvalues[1])
    sample_1_genes = [i for i, j in sample_1_values_sorted]
    sample_1_values = [j for i, j in sample_1_values_sorted]

...

with open('genes.csv') as f:
    cread = csv.reader(f, delimiter = '\t')
    sample_1_graph_un = [float(j) for i, j in cread]

sample_values_list = [i for i in sample_1_graph_un, sample_2_graph_un, sample_3_graph_un, sample_4_graph_un, sample_5_graph_un, sample_6_graph_un]

sample_graph_list_un = [[i for i in sample_value] for sample_value in sample_values_list]
colors = 'bgrcmy'
alphas = ['0.5', '0.5', '0.5', '0.5', '0.5', '0.5']
labels = ['278', '470', '543', '5934', '6102', '17163']

for graph, color, alpha, label in zip(sample_graph_list_un, colors, alphas, labels):
    plt.hist(graph, bins = 21, histtype = 'stepfilled', normed = True, color = color, alpha = float(alpha), label=label)

每個代碼示例的區別在於以下語句在兩個“ with”塊之一中的位置:

sample_1_graph_un = [float(j) for i, j in cread] 

您不能從文件或csv.reader()對象讀取兩次,而無需重新打開或倒回開始。

文件就像磁帶一樣。 當您閱讀文件時,位置會一直前進直到到達終點。 之后,嘗試從中讀取更多內容只會導致不返回任何數據。

要倒帶文件,請使用.seek()方法:

f.seek(0)

請注意,您的代碼似乎完成了很多不必要的額外工作。 [i for i in ...]僅循環遍歷輸入序列,以構建該序列的副本,而無需實際副本。

實際上,您不需要閱讀任何內容,可以將代碼簡化為:

sample_graph_list_un = []

with open('genes.csv') as f:
    cread = csv.reader(f, delimiter = '\t')
    key_values = [(i, float(j)) for i, j in cread]
    sample_genes = sorted(k for k, v in key_values)
    sample_values = [v for k, v in key_values]  # unsorted for appending first
    sample_graph_list_un.append(sample_values)
    sample_values = sorted(sample_values)       # sorted() creates a copy

注意代碼如何添加到sample_graph_list_un列表中; 絕對不需要從單獨的csv文件構建6個單獨命名的列表,然后在此處將它們合並為一個列表。

我沒有看到您如何使用排序后的_genes_values列表,我將它們包含在代碼中,但是沒有在任何地方附加它們。 以類似的方式使用它們,或者,如果您不需要在任何地方使用這些列表,請使用sorted()完全刪除這些行。

有一個非常簡單且通用的解決方案。

每當您有一個要迭代多次的迭代器(文件,CSV閱讀器,生成器,等等)時,都可以將其放入一個list

with open('genes.csv') as f:
    cread = list(csv.reader(f, delimiter = '\t'))

然后,其余代碼可以保持不變(或者可以將其拉到with語句之外):

sample_1_dict = {i: float(j) for i, j in cread}
sample_1_list = [x for x in sample_1_dict.items()]
sample_1_genes_sorted = sorted(sample_1_list, key=lambda expvalues: expvalues[0])
sample_1_values_sorted = sorted(sample_1_list, key=lambda expvalues: expvalues[1])
sample_1_genes = [i for i, j in sample_1_values_sorted]
sample_1_values = [j for i, j in sample_1_values_sorted]
sample_1_graph_un = [float(j) for i, j in cread]

這樣做的缺點是,您必須構建一個不必要的列表,並且在您閱讀完整個文件之后才能開始處理。 如果您可以將整個算法編寫為從一個迭代器到另一個迭代器(例如,生成器表達式)的一遍轉換序列,那將是一個巨大的勝利。

但是對於您而言,您已經建立了許多列表和字典,在閱讀完整個文件之前,您無法進入第二個列表和字典,因此從一開始就構建列表確實沒有成本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM