我有一个由字符串和列表组成的列表:
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)
答案 0 :(得分:1)
使用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在很多情况下可能仍会存在很长一段时间)。
答案 1 :(得分:0)
获取列表索引并使用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) )
答案 2 :(得分:0)
作为一种功能样式,您可以reduce
列表:
list(reduce(lambda x, y: (x1 + "".join(y1) for x1 in x for y1 in y), a))
['abcdefghiquv', 'abcdefghiwxy', 'abcderstiquv', 'abcderstiwxy']