在'for'循环中为每个打开的文件创建单独的列表

时间:2013-05-26 00:42:54

标签: python

我正在尝试从多个打开的文件创建列表,但有一些问题。我需要为每个文件创建两个单独的列表,现在我的代码只为最后一个迭代文件创建两个列表。建议修复,并为'file_list'中的每个文件创建唯一的'sample_genes'和'sample_values'?

或者,从所有文件为'gene_names'创建单个统一列表,从所有文件创建'sample_values'也可以。

# Parse csv files for samples, creating lists of gene names and expression values.
file_list =  ['CRPC_278.csv', 'PCaP_470.csv', 'CRPC_543.csv', 'PCaN_5934.csv', 'PCaN_6102.csv', 'PCaP_17163.csv']
des_list = ['a', 'b', 'c', 'd', 'e', 'f']
for idx, (f_in, des) in enumerate(zip(file_list, des_list)):
    with open(f_in) as des:
        cread = list(csv.reader(des, delimiter = '\t'))
        sample_genes = [i for i, j in (sorted([x for x in {i: float(j) 
                                        for i, j in cread}.items()], key = lambda v: v[1]))]        
        sample_values = [j for i, j in (sorted([x for x in {i: float(j) 
                            for i, j in cread}.items()], key = lambda v: v[1]))]

# Compute row means.
mean_values = [((a + b + c + d + e + f)/len(file_list)) for i, (a, b, c, d, e, f) in enumerate(zip(sample_1_values, sample_2_values, sample_3_values, sample_4_values, sample_5_values, sample_6_values))]

# Provide proper gene names for mean values and replace original data values by corresponding means.
sample_genes_list = [i for i in sample_1_genes, sample_2_genes, sample_3_genes, sample_4_genes, sample_5_genes, sample_6_genes]

sample_final_list = [sorted(zip(sg, mean_values)) for sg in sample_genes_list]

以下新代码:

# Parse csv files for samples, creating lists of gene names and expression values.
file_list =  ['CRPC_278.csv', 'PCaP_470.csv', 'CRPC_543.csv', 'PCaN_5934.csv', 'PCaN_6102.csv', 'PCaP_17163.csv']
full_dict = {}
for path in file_list:
    with open(path) as stream:
            data = list(csv.reader(stream, delimiter = '\t'))
    data = sorted([(i, float(j)) for i, j in data], key = lambda v: v[1])
    sample_genes = [i for i, j in data]
    sample_values = [j for i, j in data]
    full_dict[path] = (sample_genes, sample_values)

在字典中解压缩字典的结果显示了一些深层嵌套结构:

for key in full_dict: 
value = full_dict[key]
for key in full_dict[key]:
    for idx, items in enumerate(key):
        print idx

2 个答案:

答案 0 :(得分:3)

我不确定你的csv文件中有什么,但是你做了一些多余的工作,还有一些毫无意义的工作。让我们稍微打破一下:

for idx, (f_in, des) in enumerate(zip(file_list, des_list)):

idx根本不会出现在循环体中,因此您不需要enumerate

des确实出现在列表的正文中,但第一次出现在构造中:

with open(f_in) as des:

这样循环中的一个是不同的des,是打开文件的流。所以大概你也不需要zip。删除两者,你可以这样做:

for f_in in file_list:

接下来,你读了一次文件(list(csv.reader(...)),这很好。结果以名称cread保存。

然后,你将sorted的结果运行了这两个列表推导,它本身被赋予了将.items()应用于字典理解的结果的列表理解结果。外部列表推导的要点是从列表中提取一个或另一个项目:i,然后是j,来自[... for i, j in ...]

根据sorted内发生的情况,这可能是合适的,所以让我们来看看:

sorted(..., key = lambda v: v[1])

这意味着列表元素本身必须是可索引的,并且您按第二项排序(当然第一项是v[0])。

当您按第二项排序,然后取第一项并丢弃第二项时,至少不会多余。但是如果你按第二项排序,然后拿第二项并丢弃第一项,你可以简单地取第二项,然后排序并完成。 (但是,在我们走得那么远之前,让我们再检查一下。:-))

最后,让我们看一下字典理解和.items()调用。在两种情况下,dictcomp本身都是:

{i: float(j) for i, j in cread}

据推测,您的CSV文件必须为您提供配对,第一部分中的任何内容都可以用作键,而第二部分中的任何内容都可以转换为float。所以让我们来看一个带有两个键值对的简单字典,比如string-and-float:

{'a': 2.71828, 'b': 3.14159}

并申请.items()

>>> {'a': 2.71828, 'b': 3.14159}.items()
[('a', 2.71828), ('b', 3.14159)]

不是编写字典并将其折叠回2元素元组列表,而是可以使用列表推导来制作双元素元组。让我们测试一下:

>>> cread = [['a', '2.71828'], ['b', '3.14159']]
>>> [(i, float(j)) for i, j in cread]
[('a', 2.71828), ('b', 3.14159)]

现在我们可以通过它的第二个元素对这个东西进行一次排序。我们可以使用sorted,或者制作一个列表并对其进行排序,但是一旦完成,我们就保存它。在我们开始之前,我已经选择了一组糟糕的值,因为它们已经排序,让我们为cread添加一对不同的排序:

>>> cread.append(['c', '0']); print cread
[['a', '2.71828'], ['b', '3.14159'], ['c', '0']]
>>> by_second = sorted([(i, float(j)) for i, j in cread], key = lambda v: v[1])
>>> by_second
[('c', 0.0), ('a', 2.71828), ('b', 3.14159)]

保存了这个已排序的东西后,我们现在可以通过原始的list-comprehension-to-pick-item获取sample_genes和sample_values列表。我也会更改一些名字:

for path in file_list:
    with open(path) as stream:
        data = list(csv.reader(stream, delimiter = '\t'))
    data = sorted([(i, float(j)) for i, j in data], key = lambda v: v[1])
    sample_genes = [i for i, j in data]
    sample_values = [j for i, j in data]

下一步当然是以某种方式保存这些样本。据推测,您将使用idxdes_list来命名它们,但通过csv-path-name索引它们似乎更直接:

    somedict[path] = (sample_genes, sample_values)

其中somedict最初是一个空字典(在进入for循环之前创建)。在某些时候,开始考虑正确的数据结构并创建一个类是合理的。

答案 1 :(得分:0)

不确定我是否看到了问题,你不能这样做

sample_genes[idx]  = [i for i, j in (....
sample_values[idx] = [j for i, j in (....

sample_genes[des]如果您更喜欢命名属性?