我有一些效率非常低的代码,我想提高一般性/效率。我试图从一组列表中创建字符串。
以下是我目前的情况:
#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']
答案 0 :(得分:4)
我将itertools.product
与collections.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
中指定,它就应该有效。
答案 1 :(得分:0)
尝试使用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']
答案 2 :(得分: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']
答案 3 :(得分:0)
你想要它有多普遍?
>>> for item in combinations:
'_'.join(map(''.join, zip(list(itertools.chain(*numind)), item)))
'LengthLong_FungusYes'
'LengthLong_FungusNo'
'LengthMed_FungusYes'
'LengthMed_FungusNo'