在嵌套for循环中从单个迭代器创建多个字典

时间:2013-05-25 19:27:16

标签: python

我有一个嵌套列表理解,它创建了一个包含约有29,000个项目的列表的列表。我正在尝试解析这个最终数据列表,并从中创建六个单独的词典。现在代码非常简单,我需要正确的声明才能正确完成以下任务:

1。)从一个语句中创建六个词典。

2。)缩放到任何长度列表,即不对按原样显示的计数器进行硬编码。

我遇到了多个问题,并尝试了以下方法:

1。)使用while循环

2。)使用break语句,将突破最内层循环,但之后不能正确创建其他字典。也是由二进制开关设置的break语句。

3。)如果,n个索引的条件,索引从1-29,000迭代,然后重复。

请注意,为简洁起见,省略号指定了代码。

# Parse csv files for samples, creating a dictionary of key, value pairs and multiple lists.
with open('genes_1') as f:
    cread_1 = list(csv.reader(f, delimiter = '\t'))
    sample_1_values = [j for i, j in (sorted([x for x in {i: float(j) 
                        for i, j in cread_1}.items()], key = lambda v: v[1]))]
    sample_1_genes = [i for i, j in (sorted([x for x in {i: float(j) 
                            for i, j in cread_1}.items()], key = lambda v: v[1]))]

... 

# Compute row means.
mean_values = []
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)):
    mean_values.append((a + b + c + d + e + f)/6)

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

# Create multiple dictionaries from normalized values for each dataset.
class BreakIt(Exception): pass
try: 
    count = 1         
    for index, items in enumerate(sample_final_list):
        sample_1_dict_normalized = {}             
        for index, (genes, values) in enumerate(items):
            sample_1_dict_normalized[genes] = values
            count = count + 1
            if count == 29595:
                raise BreakIt
except BreakIt:
    pass

...

try: 
    count = 1         
    for index, items in enumerate(sample_final_list):
        sample_6_dict_normalized = {}             
        for index, (genes, values) in enumerate(items):
            if count > 147975:
                sample_6_dict_normalized[genes] = values
            count = count + 1
            if count == 177570:
                raise BreakIt
except BreakIt:
    pass

# Pull expression values to qualify overexpressed proteins.
print 'ERG values:'
print 'Sample 1:', round(sample_1_dict_normalized.get('ERG'), 3) 
print 'Sample 6:', round(sample_6_dict_normalized.get('ERG'), 3)  

2 个答案:

答案 0 :(得分:1)

您的代码太长,我无法给出确切的答案。我会非常普遍地回答。

首先,您无缘无故地使用enumerate。如果您不需要 索引和值,则可能不需要枚举。

这部分:

with open('genes.csv') as f:
    cread_1 = list(csv.reader(f, delimiter = '\t'))
    sample_1_dict = {i: float(j) for i, j in cread_1}
    sample_1_list = [x for x in sample_1_dict.items()]
    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_raw = [float(j) for i, j in cread_1] 

应该是(a)使用名为list的{​​{1}}和(b)更短,因为您实际上不需要从samples中提取所有这些信息并将其移动马上。它可以是:

sample_1_dict
之后,计算总和和均值会更自然。

在这部分:

samples = [None] * 6
for k in range(6):
    with open('genes.csv') as f: #but something specific to k
        cread = list(csv.reader(f, delimiter = '\t'))
        samples[k] = {i: float(j) for i, j in cread}

你应该(a)迭代前面提到的class BreakIt(Exception): pass try: count = 1 for index, items in enumerate(sample_final_list): sample_1_dict_normalized = {} for index, (genes, values) in enumerate(items): sample_1_dict_normalized[genes] = values count = count + 1 if count == 29595: raise BreakIt except BreakIt: pass 列表,并且(b)根本不使用samples,因为你可以在count或{{1}上自然迭代或类似的东西。

答案 1 :(得分:0)

您的代码有几个问题。你应该把你的代码放在最好只做一件事的函数中。比你可以为每个样本调用一个函数而不重复相同的代码六次(我假设这是省略号隐藏的。)。为每个函数提供一个自描述名称和一个解释它的功能的文档字符串。有相当多的不必要的代码。一旦你在功能中拥有它,其中一些可能会变得明显。因为函数接受参数,所以你可以提交你的29595。