python 生成list的所有的子集/幂集(不使用递归且不引入标准库,2个for循环解决)

代码

不使用递归且不引入标准库,单纯用两个for循环即可得出一个list的所有子集

LIST = [1, 2, 3, 4]
LEN_LIST = len(LIST)

lst = [[]]

for i in range(LEN_LIST):       # 固定的值
    for j in range(len(lst)):   # 变化的值(每次外层循环开始后,len(lst)发生变化)。但len(lst)在每一次内层循环开始前固定(即先计算len(lst),再进行for循环)
        sub_lst = lst[j] + [LIST[i]]
        lst.append(sub_lst)     # append不会影响本次内层循环次数

print("lst =", lst)
# 输出:lst = [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3], [4], [1, 4], [2, 4], [1, 2, 4], [3, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]

关键点

内层循环的 range(len(List)) 是在每次外层循环开始时重新计算

原理解释

从空集开始
对于原列表中的每一个元素,将它追加到当前已有的所有子集中,从而生成一批新的子集,并将它们加入结果列表
注:由于每次处理的是一个新元素,且只与已有子集组合,因此不会产生重复,也不需要去重

举例

要生成 [1, 2, 3, 4] 的子集

初始:[[]]
加入 1:[]+[1] → [1] → 结果:[[], [1]]
加入 2:[]+[2], [1]+[2] → [2],[1,2] → 结果:[[], [1], [2], [1,2]]
加入 3:[]+[3], [1]+[3], [2]+[3], [1,2]+[3] → [3],[1,3],[2,3],[1,2,3] → 结果:[[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]]
以此类推……


后记

如果考虑到程序的效率问题,那么建议引入 python 标准库中的 itertools,然后调用 combinations 这个函数
这样可以更加高效地得到一个 LIST 的所有的子集

from itertools import combinations

LIST = [1, 2, 3, 1]
LEN_LIST = len(LIST)

lst = sum([list(map(list, combinations(LIST, i))) for i in range(LEN_LIST + 1)], [])

print(lst)  # [[], [1], [2], [3], [1], [1, 2], [1, 3], [1, 1], [2, 3], [2, 1], [3, 1], [1, 2, 3], [1, 2, 1], [1, 3, 1], [2, 3, 1], [1, 2, 3, 1]]
posted @ 2019-11-10 18:35  Alan_LJP  阅读(1854)  评论(0)    收藏  举报