You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从扁平列表生成所有无重复顺序的列表与子列表组合?

生成列表的所有不重复集合划分

看起来你要解决的是集合划分问题——把原列表的所有元素分成若干非空子集,且不考虑子集的顺序(避免像[["aaa"], ["bbb"], ["ccc"]]和[["bbb"], ["aaa"], ["ccc"]]这类重复),同时每个划分必须包含所有元素。

递归实现方案

这个需求用递归的方式最直观,而且能自然避免重复。核心思路是:从第一个元素开始,要么把它单独作为一个子集,要么把它合并到后续元素的任意子集中,递归处理剩下的元素。

def set_partitions(lst):
    if not lst:
        yield []
        return
    # 取列表第一个元素
    first = lst[0]
    # 递归处理剩下的元素,得到所有可能的划分
    for rest_partition in set_partitions(lst[1:]):
        # 情况1:第一个元素单独作为一个子集
        yield [[first]] + rest_partition
        # 情况2:把第一个元素依次加入到剩余划分的每个子集中
        for i in range(len(rest_partition)):
            updated_subset = [first] + rest_partition[i]
            yield rest_partition[:i] + [updated_subset] + rest_partition[i+1:]

测试一下

用你的示例列表测试:

l = ["aaa", "bbb", "ccc"]
for partition in set_partitions(l):
    print(partition)

输出正好符合你的要求:

[['aaa'], ['bbb'], ['ccc']]
[['aaa', 'bbb'], ['ccc']]
[['aaa', 'ccc'], ['bbb']]
[['bbb', 'ccc'], ['aaa']]
[['aaa', 'bbb', 'ccc']]

为什么不会产生重复?

这个方法通过固定子集的相对顺序避免了重复:我们总是把原列表中靠前的元素优先放在划分的前面,或者合并到后续的子集中,不会出现子集顺序颠倒的情况(比如不会生成[["bbb"], ["aaa"], ["ccc"]])。

关于itertools.combinations

itertools.combinations主要用于生成元素的组合,直接用它来生成划分会比较绕——你需要先确定分组的大小,再生成对应的组合,还要处理分组的不重复问题,不如递归方案简洁直观。

内容的提问来源于stack exchange,提问作者Thomas Karaouzene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:28:13