如何在python中线性组合列表列表,而不是每个项目都是列表?

时间:2017-07-28 04:04:16

标签: python list

我有一个由字符串和列表组成的列表:

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)

3 个答案:

答案 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']