读取cread对象两次会导致'IndexError:list index out of range'

时间:2013-05-24 21:59:33

标签: python

当读取csv reader对象两次时,得到错误'IndexError:list index out of range'。现在我正在迭代对象创建一个字典,但在尝试创建类似列表时失败。为简洁起见,省略了其他代码块,以下是相关代码:

# 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] 

2 个答案:

答案 0 :(得分:2)

如果没有重新打开或倒退到开头,则无法从文件或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()完全删除这些行。

答案 1 :(得分:1)

这是一个非常简单,非常通用的解决方案。

每当你想要多次迭代的迭代器(文件,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]

执行此操作的缺点是您必须构建一个不必要的列表,并且在读取整个文件之前无法开始处理。如果您可以将整个算法编写为从一个迭代器到另一个迭代器的一次转换序列(例如,生成器表达式),那将是一个巨大的胜利。

但是在你的情况下,你已经建立了许多列表和序列,在你阅读完整个文件之前你无法进入第二个列表和序列,因此构建列表实际上没有任何成本一开始。