0

两次读取 csv 读取器对象时,出现错误“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] 
4

2 回答 2

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()如果您在任何地方都不需要这些列表,则完全删除这些行。

于 2013-05-24T22:01:22.433 回答
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]

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

但是在您的情况下,您已经构建了许多列表和字典,并且在阅读整个文件之前您无法进入第二个,因此一开始就构建列表确实没有任何成本。

于 2013-05-24T22:09:09.520 回答