在下面的代码片段中,是否有更多pythonic方法迭代列表中的每个对象,同时增加另一个对象的索引?我经常使用这个习语,认为有更好的方法。
# Creates a dictionary with normalized values for the dataset.
def exp_pull(sample, gene):
sample_name = {genes: values for genes, values in
zip([v for i, (j, k) in set_list[int(sample) - 1:int(sample)]
for v in j], mean_values)}
return round(sample_name.get(gene), 3)
# Pulls normalized expression values for particular genes for all samples.
genes_of_interest = ['ERG', 'ETV1', 'ETV4', 'ETV5']
count = 0
for gene in genes_of_interest:
print '\n'
print genes_of_interest[count], ':'
for file in file_list:
print file, ": ", exp_pull(file_list.index(file) + 1,
genes_of_interest[count])
count += 1
答案 0 :(得分:4)
您不需要在循环上有索引;您的列表中已有gene
元素。相反,您希望获得file_list
循环的计数器,它会出现,并避免(昂贵的)file_list.index()
调用。使用enumerate()
function可以实现:
for gene in genes_of_interest:
print '\n{}:'.format(gene)
for i, file in enumerate(file_list):
print '{}: {}'.format(file, exp_pull(i, gene))
这使用字符串格式化以高效和紧凑的方式组合输出。
现在第一个参数是始终一个整数,因此您可以放弃int()
中的exp_pull()
来电。你也只是从set_list()
切出一个元素,所以通过传入file_list
索引(不加一)你可以简化过度复杂exp_pull()
到:
def exp_pull(sample, gene):
if sample >= len(set_list):
# no such entry in set_list
return 0.0
i, (j, k) = set_list[sample]
sample_name = dict(zip(j, mean_values))
return round(sample_name.get(gene, 0), 3)
这样就不再需要嵌套的理解;我还在sample_name.get()
调用中添加了默认值,因为round()
会在返回正常默认值None
时抛出异常。
我怀疑你的程序的其余部分可以做类似的简化;您可能希望将其发布在https://codereview.stackexchange.com/上,以了解还有哪些内容可以调整。
答案 1 :(得分:1)
看起来你想要enumerate()
:
for indx, gene in enumerate(genes_of_interest):
print '\n'
print genes_of_interest[indx], ':'
for indx2, file in enumerate(file_list, 1):
print file, ": ", exp_pull(indx2,
genes_of_interest[indx])
但不管怎样,这都是毫无意义的。您已经在列表中进行迭代,为每个项目命名为gene
。当你可以使用gene
时,无需通过索引访问完全相同的元素,例如:
for gene in genes_of_interest:
print '\n'
print gene, ':'
for indx, file in enumerate(file_list, 1):
print file, ": ", exp_pull(indx,
gene)
enumerate()
接受第二个参数, start 。您可以从 n 开始,而不是从0开始。