我基本上是在寻找一个python版本的组合列表<列表<int>>
给定一个列表的列表,我需要一个新的列表,它给出列表之间所有可能的项目组合。
[[1,2,3],[4,5,6],[7,8,9,10]] -> [[1,4,7],[1,4,8],...,[3,6,10]]
列表的数量是未知的,所以我需要对所有情况都适用的东西。优雅的加分!
我基本上是在寻找一个python版本的组合列表<列表<int>>
给定一个列表的列表,我需要一个新的列表,它给出列表之间所有可能的项目组合。
[[1,2,3],[4,5,6],[7,8,9,10]] -> [[1,4,7],[1,4,8],...,[3,6,10]]
列表的数量是未知的,所以我需要对所有情况都适用的东西。优雅的加分!
当前回答
这个答案不像使用itertools那么简洁,但这个想法可能是有用的。
从这里的zip()构造中获得灵感,我们可以执行以下操作。
>>> a = iter([[1,2,3],[4,5,6],[7,8,9,10]])
>>> sentinel = object()
>>> result = [[]]
>>> while True:
>>> l = next(a,sentinel)
>>> if l == sentinel:
>>> break
>>> result = [ r + [digit] for r in result for digit in l]
>>> print(result)
[[1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 4, 10], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 5, 10], [1, 6, 7], [1, 6, 8], [1, 6, 9], [1, 6, 10], [2, 4, 7], [2, 4, 8], [2, 4, 9], [2, 4, 10], [2, 5, 7], [2, 5, 8], [2, 5, 9], [2, 5, 10], [2, 6, 7], [2, 6, 8], [2, 6, 9], [2, 6, 10], [3, 4, 7], [3, 4, 8], [3, 4, 9], [3, 4, 10], [3, 5, 7], [3, 5, 8], [3, 5, 9], [3, 5, 10], [3, 6, 7], [3, 6, 8], [3, 6, 9], [3, 6, 10]]
我们使用a作为迭代器是为了连续获取它的下一项,而不需要知道有多少个先验项。当我们用光a中的列表时,下一个命令将输出sentinel(这是一个专门用于进行比较的对象,请参阅这里的解释),导致if语句触发,从而跳出循环。
其他回答
Numpy可以做到:
>>> import numpy
>>> a = [[1,2,3],[4,5,6],[7,8,9,10]]
>>> [list(x) for x in numpy.array(numpy.meshgrid(*a)).T.reshape(-1,len(a))]
[[ 1, 4, 7], [1, 5, 7], [1, 6, 7], ....]
from itertools import product
list_vals = [['Brand Acronym:CBIQ', 'Brand Acronym :KMEFIC'],['Brand Country:DXB','Brand Country:BH']]
list(product(*list_vals))
输出:
[('品牌首字母缩写:CBIQ', '品牌国家:DXB'), (“品牌首字母缩写:CBIQ”,“品牌国家:BH”), (“品牌首字母缩写:KMEFIC”,“品牌国家:DXB”), (“品牌首字母缩写:KMEFIC”,“品牌国家:BH”)]
这个答案不像使用itertools那么简洁,但这个想法可能是有用的。
从这里的zip()构造中获得灵感,我们可以执行以下操作。
>>> a = iter([[1,2,3],[4,5,6],[7,8,9,10]])
>>> sentinel = object()
>>> result = [[]]
>>> while True:
>>> l = next(a,sentinel)
>>> if l == sentinel:
>>> break
>>> result = [ r + [digit] for r in result for digit in l]
>>> print(result)
[[1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 4, 10], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 5, 10], [1, 6, 7], [1, 6, 8], [1, 6, 9], [1, 6, 10], [2, 4, 7], [2, 4, 8], [2, 4, 9], [2, 4, 10], [2, 5, 7], [2, 5, 8], [2, 5, 9], [2, 5, 10], [2, 6, 7], [2, 6, 8], [2, 6, 9], [2, 6, 10], [3, 4, 7], [3, 4, 8], [3, 4, 9], [3, 4, 10], [3, 5, 7], [3, 5, 8], [3, 5, 9], [3, 5, 10], [3, 6, 7], [3, 6, 8], [3, 6, 9], [3, 6, 10]]
我们使用a作为迭代器是为了连续获取它的下一项,而不需要知道有多少个先验项。当我们用光a中的列表时,下一个命令将输出sentinel(这是一个专门用于进行比较的对象,请参阅这里的解释),导致if语句触发,从而跳出循环。
只需使用itertools.product:
listOLists = [[1,2,3],[4,5,6],[7,8,9,10]]
for l in itertools.product(*listOLists):
print(l)
对于这个任务,直接递归没有错,不需要外部依赖,如果你需要一个处理字符串的版本,这可能适合你的需求:
combinations = []
def combine(terms, accum):
last = (len(terms) == 1)
n = len(terms[0])
for i in range(n):
item = accum + terms[0][i]
if last:
combinations.append(item)
else:
combine(terms[1:], item)
>>> a = [['ab','cd','ef'],['12','34','56']]
>>> combine(a, '')
>>> print(combinations)
['ab12', 'ab34', 'ab56', 'cd12', 'cd34', 'cd56', 'ef12', 'ef34', 'ef56']