如何在python中线性组合列表列表,而不是每个项目都是列表?
问题描述:
我有一个字符串和列表组成的列表:如何在python中线性组合列表列表,而不是每个项目都是列表?
a = ['a', 'b', 'c', 'd', 'e', ['fgh', 'rst'], 'i',['quv','wxy']]
如何加入每一个元素在此列表中,这样所有的字符串元素包含每个内部列表元素之一,同时保持其原来的位置清单?例如:
targets = ['abcdefghiquv',
'abcdefghiwxy',
'abcderstiquv',
'abcderstiwxy',
]
我在下面的方式尝试过,但是,如果最后一个元素是一个列表
combinations = []
combinations2 = []
for s in a:
if isinstance(s, basestring):
combinations.append(s)
else:
seqint = ''.join(combinations)
combinations2.append([seqint])
combinations2.append(s)
combinations[:]=[]
for comb in list(itertools.product(*combinations2)):
print ''.join(comb)
答
使用itertools.product
肯定是要走的路这仅适用。我会做这种方式(可能不完全正确的,因为我从来没有使用传统的Python多):
# helper function
def strtolist(o):
'''Takes an object and puts it in a list if it's a string'''
if isinstance(o, str):
return [o]
return o
a = ['a', 'b', 'c', 'd', 'e', ['fgh', 'rst'], 'i',['quv','wxy']]
newa = [strtolist(item) for item in a]
这最后一步被称为列表理解。它们非常有用,因此它可以很好地利用时间去阅读它们(还有字典理解和生成器理解)。
现在我们有一个新的列表,看起来像这样:
newa = [['a'], ['b'], ['c'], ['d'], ['e'], ['fgh', 'rst'], ['i'],['quv','wxy']]
然后完成了同之前一样:
from itertools import product
for comb in list(product(*newa)):
print ''.join(comb)
编辑:如果你真的想要得到粗糙,你可以在一个陈述中完成所有这些。但我不建议这样做(不是很可读):
>>> result = [''.join(combo) for combo in product(*[([item] if isinstance(item, basestr) else item) for item in a])]
>>> assert result == targets
# no error: success
好像你是在学习,所以我会做一个附加注释的过程:除非你有一个很好的理由使用传统学习Python(2),我建议切换到现代Python(当前版本3.6)。这是目前所有的方向(尽管传统的Python在很多情况下可能还会存在很长一段时间)。
答
通过获取列表索引和使用itertools.product
a = ['a', 'b', 'c', 'd', 'e', ['fgh', 'rst'], 'i',['quv','wxy'] ]
idx = []
lst = []
for i in a:
if isinstance(i, list):
idx.append(a.index(i))
lst.append(i)
from itertools import product
for j in [ dict(zip(idx,i)) for i in product(*lst) ] :
for k,v in j.items():
a[k] = v
print (''.join(a))
答
作为一个实用的风格,你可以reduce
列表中的另一种方法:
list(reduce(lambda x, y: (x1 + "".join(y1) for x1 in x for y1 in y), a))
['abcdefghiquv', 'abcdefghiwxy', 'abcderstiquv', 'abcderstiwxy']
你尝试过什么已经试图解决这个问题?你能展示你的代码并解释你面临的困难吗? – idjaw