嵌套循环 n 次以将列表的子列表添加到自身

nesting for loop n times to add sublists of a list to itself

提问人:propotato 提问时间:10/12/2023 最后编辑:Kelly Bundypropotato 更新时间:10/13/2023 访问量:152

问:

假设我有一个列表 list_ = [['a'],['b'],['c']],我想编写一个程序,通过遍历每个元素来添加这个列表,然后将结果写入主列表 (这里 n 是 (len(list_)-1))

这是我到目前为止所写的

list_ = [['a'],['b'],['c']]
result = []
for i in list_:
    for j in list_:
        x = i+j
        result.append(x)
print(result)

现在我想如果我有一个 ex list_ = [['a'],['b'],['c'],['d']] 的 4 个子列表列表,我正在做

list_ = [['a'],['b'],['c'],['d']]
result = []
for i in list_:
    for j in list_:
        for k in list_:
            x = i+j+k
            result.append(x)
print(result)

我如何使用递归或 IterTools 或更好的东西为 n 个子列表的列表编写一个遵循相同模式的函数。如果我无法正确解释问题,我深表歉意。

我想使用上面的逻辑重写任意数量的字母表的第 15-17 行list_

from itertools import chain, combinations, product

def powerset(iterable):
        s = list(iterable)
        pset = []
        for s in list(chain.from_iterable(combinations(s, r) for r in range(len(s)+1))):
             pset.append(list(s))
    
        return pset
    
list_ = ['a','b','c'] 
test_list = powerset(list_)
list_1 = []
list_2 = []
for i in test_list:
    for j in test_list:
        x = i+j
        if len(x)==len(list_):
            if len(x) == len(set(x)):
                list_2.append(i)
                list_2.append(j)
                list_1.append(list_2)
                list_2 = []

print(list_1)

所需输出

[
    [[], ['a', 'b', 'c']],
    [['a'], ['b', 'c']],
    [['b'], ['a', 'c']],
    [['c'], ['a', 'b']],
    [['a', 'b'], ['c']],
    [['a', 'c'], ['b']],
    [['b', 'c'], ['a']],
    [['a', 'b', 'c'], []]
]

因此,如果有四个字母,代码将如下所示

list_ = ['a','b','c','d'] 
test_list = powerset(list_)
list_1 = []
list_2 = []
for i in test_list:
    for j in test_list:
        for k in test_list:
            x = i+j+k
            if len(x)==len(list_):
                if len(x) == len(set(x)):
                    list_2.append(i)
                    list_2.append(j)
                    list_2.append(k)
                    list_1.append(list_2)
                    list_2 = []
      

print(list_1)

输出

[[[], [], ['a', 'b', 'c', 'd']], [[], ['a'], ['b', 'c', 'd']], [[], ['b'], ['a', 'c', 'd']], [[], ['c'], ['a', 'b', 'd']], [[], ['d'], ['a', 'b', 'c']], [[], ['a', 'b'], ['c', 'd']], [[], ['a', 'c'], ['b', 'd']], [[], ['a', 'd'], ['b', 'c']], [[], ['b', 'c'], ['a', 'd']], [[], ['b', 'd'], ['a', 'c']], [[], ['c', 'd'], ['a', 'b']], [[], ['a', 'b', 'c'], ['d']], [[], ['a', 'b', 'd'], ['c']], [[], ['a', 'c', 'd'], ['b']], [[], ['b', 'c', 'd'], ['a']], [[], ['a', 'b', 'c', 'd'], []], [['a'], [], ['b', 'c', 'd']], [['a'], ['b'], ['c', 'd']], [['a'], ['c'], ['b', 'd']], [['a'], ['d'], ['b', 'c']], [['a'], ['b', 'c'], ['d']], [['a'], ['b', 'd'], ['c']], [['a'], ['c', 'd'], ['b']], [['a'], ['b', 'c', 'd'], []], [['b'], [], ['a', 'c', 'd']], [['b'], ['a'], ['c', 'd']], [['b'], ['c'], ['a', 'd']], [['b'], ['d'], ['a', 'c']], [['b'], ['a', 'c'], ['d']], [['b'], ['a', 'd'], ['c']], [['b'], ['c', 'd'], ['a']], [['b'], ['a', 'c', 'd'], []], [['c'], [], ['a', 'b', 'd']], [['c'], ['a'], ['b', 'd']], [['c'], ['b'], ['a', 'd']], [['c'], ['d'], ['a', 'b']], [['c'], ['a', 'b'], ['d']], [['c'], ['a', 'd'], ['b']], [['c'], ['b', 'd'], ['a']], [['c'], ['a', 'b', 'd'], []], [['d'], [], ['a', 'b', 'c']], [['d'], ['a'], ['b', 'c']], [['d'], ['b'], ['a', 'c']], [['d'], ['c'], ['a', 'b']], [['d'], ['a', 'b'], ['c']], [['d'], ['a', 'c'], ['b']], [['d'], ['b', 'c'], ['a']], [['d'], ['a', 'b', 'c'], []], [['a', 'b'], [], ['c', 'd']], [['a', 'b'], ['c'], ['d']], [['a', 'b'], ['d'], ['c']], [['a', 'b'], ['c', 'd'], []], [['a', 'c'], [], ['b', 'd']], [['a', 'c'], ['b'], ['d']], [['a', 'c'], ['d'], ['b']], [['a', 'c'], ['b', 'd'], []], [['a', 'd'], [], ['b', 'c']], [['a', 'd'], ['b'], ['c']], [['a', 'd'], ['c'], ['b']], [['a', 'd'], ['b', 'c'], []], [['b', 'c'], [], ['a', 'd']], [['b', 'c'], ['a'], ['d']], [['b', 'c'], ['d'], ['a']], [['b', 'c'], ['a', 'd'], []], [['b', 'd'], [], ['a', 'c']], [['b', 'd'], ['a'], ['c']], [['b', 'd'], ['c'], ['a']], [['b', 'd'], ['a', 'c'], []], [['c', 'd'], [], ['a', 'b']], [['c', 'd'], ['a'], ['b']], [['c', 'd'], ['b'], ['a']], [['c', 'd'], ['a', 'b'], []], [['a', 'b', 'c'], [], ['d']], [['a', 'b', 'c'], ['d'], []], [['a', 'b', 'd'], [], ['c']], [['a', 'b', 'd'], ['c'], []], [['a', 'c', 'd'], [], ['b']], [['a', 'c', 'd'], ['b'], []], [['b', 'c', 'd'], [], ['a']], [['b', 'c', 'd'], ['a'], []], [['a', 'b', 'c', 'd'], [], []]]
递归 python-itertools

评论


答:

1赞 Andrej Kesely 10/12/2023 #1

IIUC,您可以使用带有参数的 itertools.productrepeat=

from itertools import product

list_ = [["a"], ["b"], ["c"]]

out = [[v for l in c for v in l] for c in product(list_, repeat=len(list_) - 1)]
print(out)

指纹:

[['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'a'], ['b', 'b'], ['b', 'c'], ['c', 'a'], ['c', 'b'], ['c', 'c']]

评论

0赞 propotato 10/12/2023
谢谢。我认为它适用于我的用例,但不确定如何实现它。我已经在问题中发布了完整的代码。
1赞 Michael H 10/12/2023 #2

我认为这就是你想要的:

from pprint import pprint


LIST = ['a', 'b', 'c', 'd']


def indexset(list_):
    n = len(list_)
    powset, difset = [set()], [set(range(n))]
    for i in set(range(n)):
        powset += [_ | {i} for _ in powset]
        difset += [_ - {i} for _ in difset]
    return powset, difset


def mapindex(list_):
    _mapindex = lambda set_: [list_[i] for i in set_]
    result = []
    for p, d in zip(*indexset(list_)):
        result.append(list(map(_mapindex, [p, d])))
    return result


result = mapindex(LIST)
pprint(sorted(result, key=lambda x: len(x[0])))  # just format!
'''
[[[], ['a', 'b', 'c', 'd']],
 [['a'], ['b', 'c', 'd']],
 [['b'], ['a', 'c', 'd']],
 [['c'], ['a', 'b', 'd']],
 [['d'], ['a', 'b', 'c']],
 [['a', 'b'], ['c', 'd']],
 [['a', 'c'], ['b', 'd']],
 [['b', 'c'], ['a', 'd']],
 [['a', 'd'], ['b', 'c']],
 [['b', 'd'], ['a', 'c']],
 [['c', 'd'], ['a', 'b']],
 [['a', 'b', 'c'], ['d']],
 [['a', 'b', 'd'], ['c']],
 [['a', 'c', 'd'], ['b']],
 [['b', 'c', 'd'], ['a']],
 [['a', 'b', 'c', 'd'], []]]
'''

评论

0赞 propotato 10/12/2023
这很有帮助,谢谢!我如何获得像 [['a']、['b']、['c'、'd']] 等情况。在上述情况下的输出中。也许我没有完全遵循这一点。
1赞 rr_goyal 10/12/2023
你确定这是一个有效的结果吗?[['a'],['b'],['c','d']]
0赞 propotato 10/12/2023
@rr_goyal是的,因为基本上我想要的是子字节的所有组合,而只使用了一次父列表的每个元素。因此,在这种情况下,是解决方案之一,如果是解决方案之一['a','b','c','d'][['a'],['c'],['b','d']]['a','b','c','d','e'][['a'],['b','c','d'],['e']]
1赞 Alain T. 10/12/2023 #3

您可以从生成给定列表的 N 个分区的递归函数开始。这可以使用 itertools.combinations 来实现,方法是将左侧的左侧和右侧的组合配对,这些组合在左侧大小递增,在右侧则倒数。递归将对每个左侧组合在右侧重复分离过程:

def partitions(L,n):
    if n == 1:
        yield [[*L]]
        return
    indexSet = set(range(len(L)))
    for size in range(len(L)+1):
        for iLeft in combinations(range(len(L)),size):
            left  = [L[i] for i in iLeft]
            right = [L[i] for i in indexSet.difference(iLeft)] 
            for rest in partitions(right,n-1):
                yield [left,*rest]

输出:

print(*partitions(['a','b','c'],2),sep="\n")
[[], ['c', 'b', 'a']]
[['a'], ['c', 'b']]
[['b'], ['c', 'a']]
[['c'], ['b', 'a']]
[['a', 'b'], ['c']]
[['a', 'c'], ['b']]
[['b', 'c'], ['a']]
[['a', 'b', 'c'], []]

然后,您可以使用这个广义分区函数(实际上是生成器)来获取列表列表的 length-1 分区,并随时合并子列表:

def partLists(L):
    for parts in partitions(L,len(L)-1):
        yield [ [i for v in p for i in v] for p in parts ]

输出:

print(*partLists([['a'],['b'],['c'],['d']]),sep="\n")
[[], [], ['a', 'b', 'c', 'd']]
[[], ['a'], ['b', 'c', 'd']]
[[], ['b'], ['a', 'c', 'd']]
[[], ['c'], ['a', 'b', 'd']]
[[], ['d'], ['a', 'b', 'c']]
[[], ['a', 'b'], ['c', 'd']]
[[], ['a', 'c'], ['b', 'd']]
[[], ['a', 'd'], ['b', 'c']]
[[], ['b', 'c'], ['a', 'd']]
[[], ['b', 'd'], ['a', 'c']]
[[], ['c', 'd'], ['a', 'b']]
[[], ['a', 'b', 'c'], ['d']]
[[], ['a', 'b', 'd'], ['c']]
[[], ['a', 'c', 'd'], ['b']]
[[], ['b', 'c', 'd'], ['a']]
[[], ['a', 'b', 'c', 'd'], []]
[['a'], [], ['b', 'c', 'd']]
[['a'], ['b'], ['c', 'd']]
[['a'], ['c'], ['b', 'd']]
[['a'], ['d'], ['b', 'c']]
[['a'], ['b', 'c'], ['d']]
[['a'], ['b', 'd'], ['c']]
[['a'], ['c', 'd'], ['b']]
[['a'], ['b', 'c', 'd'], []]
[['b'], [], ['a', 'c', 'd']]
[['b'], ['a'], ['c', 'd']]
[['b'], ['c'], ['a', 'd']]
[['b'], ['d'], ['a', 'c']]
[['b'], ['a', 'c'], ['d']]
[['b'], ['a', 'd'], ['c']]
[['b'], ['c', 'd'], ['a']]
[['b'], ['a', 'c', 'd'], []]
[['c'], [], ['a', 'b', 'd']]
[['c'], ['a'], ['b', 'd']]
[['c'], ['b'], ['a', 'd']]
[['c'], ['d'], ['a', 'b']]
[['c'], ['a', 'b'], ['d']]
[['c'], ['a', 'd'], ['b']]
[['c'], ['b', 'd'], ['a']]
[['c'], ['a', 'b', 'd'], []]
[['d'], [], ['a', 'b', 'c']]
[['d'], ['a'], ['b', 'c']]
[['d'], ['b'], ['a', 'c']]
[['d'], ['c'], ['a', 'b']]
[['d'], ['a', 'b'], ['c']]
[['d'], ['a', 'c'], ['b']]
[['d'], ['b', 'c'], ['a']]
[['d'], ['a', 'b', 'c'], []]
[['a', 'b'], [], ['c', 'd']]
[['a', 'b'], ['c'], ['d']]
[['a', 'b'], ['d'], ['c']]
[['a', 'b'], ['c', 'd'], []]
[['a', 'c'], [], ['b', 'd']]
[['a', 'c'], ['b'], ['d']]
[['a', 'c'], ['d'], ['b']]
[['a', 'c'], ['b', 'd'], []]
[['a', 'd'], [], ['b', 'c']]
[['a', 'd'], ['b'], ['c']]
[['a', 'd'], ['c'], ['b']]
[['a', 'd'], ['b', 'c'], []]
[['b', 'c'], [], ['a', 'd']]
[['b', 'c'], ['a'], ['d']]
[['b', 'c'], ['d'], ['a']]
[['b', 'c'], ['a', 'd'], []]
[['b', 'd'], [], ['a', 'c']]
[['b', 'd'], ['a'], ['c']]
[['b', 'd'], ['c'], ['a']]
[['b', 'd'], ['a', 'c'], []]
[['c', 'd'], [], ['a', 'b']]
[['c', 'd'], ['a'], ['b']]
[['c', 'd'], ['b'], ['a']]
[['c', 'd'], ['a', 'b'], []]
[['a', 'b', 'c'], [], ['d']]
[['a', 'b', 'c'], ['d'], []]
[['a', 'b', 'd'], [], ['c']]
[['a', 'b', 'd'], ['c'], []]
[['a', 'c', 'd'], [], ['b']]
[['a', 'c', 'd'], ['b'], []]
[['b', 'c', 'd'], [], ['a']]
[['b', 'c', 'd'], ['a'], []]
[['a', 'b', 'c', 'd'], [], []]

[编辑]通过优化分区函数可以更好地避免重复,但也可以使用集合(需要将它们转换为元组)在生成的分区上完成:

def partLists(L):
    seen = set()
    for parts in partitions(L,len(L)-1):
        p = [ tuple(sorted(i for v in p for i in v)) for p in parts ]
        p = tuple(sorted(p))
        if p not in seen:
            yield list(map(list,p))
            seen.add(p)

滤波输出:

print(*partLists([['a'],['b'],['c'],['d']]),sep="\n")
[[], [], ['a', 'b', 'c', 'd']]
[[], ['a'], ['b', 'c', 'd']]
[[], ['a', 'c', 'd'], ['b']]
[[], ['a', 'b', 'd'], ['c']]
[[], ['a', 'b', 'c'], ['d']]
[[], ['a', 'b'], ['c', 'd']]
[[], ['a', 'c'], ['b', 'd']]
[[], ['a', 'd'], ['b', 'c']]
[['a'], ['b'], ['c', 'd']]
[['a'], ['b', 'd'], ['c']]
[['a'], ['b', 'c'], ['d']]
[['a', 'd'], ['b'], ['c']]
[['a', 'c'], ['b'], ['d']]
[['a', 'b'], ['c'], ['d']]

评论

0赞 propotato 10/13/2023
我怎样才能从输出中多拉重复。我关心独特的组合。例如,与[['a'], ['b', 'c']][['b', 'c'], ['a']]
0赞 propotato 10/13/2023
我想我放弃了这样的实例,[[],['b'],['a','c','d']][[],['c'],['a','b','d']]
0赞 Alain T. 10/13/2023
是的,我的错,重新加工过滤器......
0赞 Alain T. 10/13/2023
现在已修复,虽然不是我想要的理想过滤器
0赞 propotato 10/13/2023
这应该适用于用例,谢谢!我打算将此功能应用于一个数据框,我想在其中获取每个父组中所有此类 df 行的组合。