2013-08-27 56 views
5

我有一些非常低效的代码,我希望使其更通用/高效。我正尝试从一组列表中创建字符串。从列表中创建字符串的有效方法

这是我目前有:

#contains categories 
numind = [('Length',), ('Fungus',)] 

#contains values that pertain to the categories 
records = [('Length', 'Long'), ('Length', 'Med'), ('Fungus', 'Yes'), ('Fungus', 'No')] 

#contains every combination of values between the 2 categories. 
#for example, (Long, Yes) = Length=Long & Fungus = Yes. 
combinations = [('Long', 'Yes'), ('Long', 'No'), ('Med', 'Yes'), ('Med', 'No')] 

现在我想创建一个在我的组合列表中的每个组合的字符串。这是效率低下的部分。我喜欢它,所以我不必硬编码“numind”列表的长度。有任何想法吗?

values = combinations 
valuestring = [] 

if len(numind) == 0: 
    pass 
elif len(numind) == 1: 
    for a in xrange(len(values)): 
     valuestring.append(numind[0][0]+values[a][0]) 

elif len(numind) == 2: 
    for a in xrange(len(values)): 
     valuestring.append(numind[0][0]+values[a][0]+'_'+numind[1][0]+values[a][1]) 

#and so forth until numind is 10+ 

输出

['LengthLong_FungusYes', 'LengthLong_FungusNo', 'LengthMed_FungusYes', 'LengthMed_FungusNo'] 

回答

4

我会使用itertools.productcollections.OrderedDict(后者不是绝对必要的,但同时也意味着你获得订单的权利,而不必去想它):

>>> from collections import OrderedDict 
>>> from itertools import product 
>>> 
>>> d = OrderedDict() 
>>> for k, v in records: 
...  d.setdefault(k, []).append(v) 
...  
>>> d 
OrderedDict([('Length', ['Long', 'Med']), ('Fungus', ['Yes', 'No'])]) 
>>> ['_'.join(k+v for k,v in zip(d, v)) for v in product(*d.values())] 
['LengthLong_FungusYes', 'LengthLong_FungusNo', 'LengthMed_FungusYes', 'LengthMed_FungusNo'] 

itertools.product自然产生“每个组合”部分(这实际上被称为笛卡尔积,而不是组合):

>>> product(["Long", "Med"], ["Yes", "No"]) 
<itertools.product object at 0x96b0dec> 
>>> list(product(["Long", "Med"], ["Yes", "No"])) 
[('Long', 'Yes'), ('Long', 'No'), ('Med', 'Yes'), ('Med', 'No')] 

这样做的优点是,它并没有多么许多类别有或有多少个值与任何类别相关联:只要他们在records会规定,它应该工作。

+0

太棒了!伟大的代码人。也感谢解释! – nlr25

0

使用try itertools

s = 'Length%s_Fungus%s' 
l1 = ['Long', 'Med'] 
l2 = ['Yes', 'No'] 
[s%x for x in itertools.product(l1, l2)] 

这就产生

['LenLong_FungusYes', 
'LenMed_FungusNo', 
'LenMed_FungusYes', 
'LenLong_FungusNo'] 
0
>>> numind = [('Length',), ('Fungus',)] 
>>> combinations = [('Long', 'Yes'), ('Long', 'No'), ('Med', 'Yes'), ('Med', 'No')] 
>>> ['_'.join(numind[i][0] + v for i, v in enumerate(c)) for c in combinations] 
['LengthLong_FungusYes', 'LengthLong_FungusNo', 'LengthMed_FungusYes', 'LengthMed_FungusNo'] 
0

你怎么一般希望它是什么?

>>> for item in combinations: 
    '_'.join(map(''.join, zip(list(itertools.chain(*numind)), item))) 


'LengthLong_FungusYes' 
'LengthLong_FungusNo' 
'LengthMed_FungusYes' 
'LengthMed_FungusNo' 
相关问题