ChatGPT解决这个技术问题 Extra ChatGPT

列表列表的所有组合[重复]

这个问题在这里已经有了答案:获取一系列列表的笛卡尔积? (16 个回答) 27 天前关闭。

我基本上是在寻找 Combination of List<List<int>> 的 python 版本

给定一个列表列表,我需要一个新列表,它给出列表之间所有可能的项目组合。

[[1,2,3],[4,5,6],[7,8,9,10]] -> [[1,4,7],[1,4,8],...,[3,6,10]]

列表的数量是未知的,所以我需要适用于所有情况的东西。优雅加分!


t
trss

您需要 itertools.product

>>> import itertools
>>> a = [[1,2,3],[4,5,6],[7,8,9,10]]
>>> list(itertools.product(*a))
[(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 表示这些是传递给函数或方法的参数。 def fn(a,b,c): 会回复 fn(*[1,2,3]) reference
@mjallday,是否可以添加这些组合:(7,4,1),(8,4,1),(9,4,1),(10,4,1),(7,5, 1),(8,5,1),(9,5,1),(10,5,1) 等等?
@Reman这并不完全清楚你想要得到什么,但如果它也是每个元组的反转,你可以使用一个将 a 作为输入的包装函数,迭代 itertools.product(*a)yield s itertools 产生的元组和一个反向版本(例如创建一个列表,reverse() 它并转换回元组)。最好问一个新问题。
如果您熟悉 javascript [*a] 将与 js 扩展运算符 [...a] 相同。这也适用于 dicts
v
vinzee

最优雅的解决方案是在 python 2.6 中使用 itertools.product

如果您不使用 Python 2.6,itertools.product 的文档实际上显示了一个等效的函数来以“手动”方式完成产品:

def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

K
Karl Knechtel

只需使用 itertools.product

listOLists = [[1,2,3],[4,5,6],[7,8,9,10]]
for l in itertools.product(*listOLists):
    print(l)

d
duanev

此任务的直接递归没有错,不需要外部依赖项,如果您需要一个与字符串一起使用的版本,这可能符合您的需求:

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

C
Community

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], ....]

有人可以解释一下吗?
如果 a 中的东西是数组,这不起作用。 a=[[[array A], [array B], [array C]], [...]
这感觉就像在问“我如何烧水”,而不是说“使用水壶”,而是“降低水周围的大气压力”。两者都有效!
r
rnso

为此,可以使用基础 python。该代码需要一个函数来展平列表列表:

def flatten(B):    # function needed for code below;
    A = []
    for i in B:
        if type(i) == list: A.extend(i)
        else: A.append(i)
    return A

然后可以运行:

L = [[1,2,3],[4,5,6],[7,8,9,10]]

outlist =[]; templist =[[]]
for sublist in L:
    outlist = templist; templist = [[]]
    for sitem in sublist:
        for oitem in outlist:
            newitem = [oitem]
            if newitem == [[]]: newitem = [sitem]
            else: newitem = [newitem[0], sitem]
            templist.append(flatten(newitem))

outlist = list(filter(lambda x: len(x)==len(L), templist))  # remove some partial lists that also creep in;
print(outlist)

输出:

[[1, 4, 7], [2, 4, 7], [3, 4, 7], 
[1, 5, 7], [2, 5, 7], [3, 5, 7], 
[1, 6, 7], [2, 6, 7], [3, 6, 7], 
[1, 4, 8], [2, 4, 8], [3, 4, 8], 
[1, 5, 8], [2, 5, 8], [3, 5, 8], 
[1, 6, 8], [2, 6, 8], [3, 6, 8], 
[1, 4, 9], [2, 4, 9], [3, 4, 9], 
[1, 5, 9], [2, 5, 9], [3, 5, 9], 
[1, 6, 9], [2, 6, 9], [3, 6, 9], 
[1, 4, 10], [2, 4, 10], [3, 4, 10], 
[1, 5, 10], [2, 5, 10], [3, 5, 10], 
[1, 6, 10], [2, 6, 10], [3, 6, 10]]

c
cellepo

这主要模仿使用 itertools.productAnswer by Jarret Hardie 等解决方案,但有以下区别:

这会将参数传递给 itertools.product 内联,而不是通过变量 a - 因此内联参数不需要 *args 语法

如果你的 mypy type-linter 像我的一样,你可以让你的代码使用带有内联产品参数的 *args 语法“工作”(如 product(*[[1,2,3],[4,5,6 ],[7,8,9,10]])),mypy 可能仍会失败(出现类似错误:“product”的重载变体与参数类型“List [object]”匹配)

因此,mypy 的解决方案是不使用 *args 语法,如下所示:

    >>> import itertools
    >>> list(itertools.product([1,2,3],[4,5,6],[7,8,9,10]))
    [(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)]

K
Kweku A

这个答案不像使用 itertools 那样干净,但这些想法可能很有用。

从 zip() here 的构造中汲取灵感,我们可以执行以下操作。

>>> 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 中的列表时,next 命令将输出 sentinel(这是一个仅为进行此比较而创建的对象,请参阅 here 以获得一些解释),从而导致 if 语句触发我们跳出循环。


实际上,这或多或少是 itertools.product 所做的——参见 here——除了使用哨兵而 itertools.product 使用 yield
M
MartenCatcher
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')]


这个答案应该被接受,因为它是唯一一个使用内置函数的答案,同时强调它也适用于任何类型和异构类型。
这个答案与多年前提供的答案有何不同?
这里的参数类型是同质的,而不是异质的。