谁能解释一下这个在Python中寻找一个集合的所有子集的逻辑?

问题描述 投票:0回答:1

我遇到了这个在Python中寻找一个集合的子集的解决方案。我不能完全抓住这个逻辑。有人能解释一下吗?

f = lambda x: [[y for j, y in enumerate(set(x)) if (i >> j) & 1] for i in range(2**len(set(x)))]
f([1,2,3])

Output:
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
python subset
1个回答
1
投票

核心思想是利用整数的二进制表示法,并检查出 j 迭代整数的第几位 i 中的每个元素。顺便说一下,这个算法适用于任何可迭代的元素,而不仅仅是集合。

这里是一个详细的版本,它打印出了推理的每一步。

  • "组合指数 "和它的二进制表示方式 === 标题行
  • 中各成员指数的测试结果 x: 十进制的索引,二进制的索引,组合索引中的memberindex'th位是否被设置,以及成员本身。
  • 由此产生的组合在 ->
def combinations(x):
    for i in range(2 ** len(x)):
        print(f"=== {i} / {i:08b}")
        result = []
        for j, member in enumerate(x):
            flag = (i >> j) & 1
            print(j, f"{j:08b}", flag, member)
            if flag:
                result.append(member)
        print("-> ", result)


combinations(["foo", "bar", "fjord"])

打印出

=== 0 / 00000000
0 00000000 0 foo
1 00000001 0 bar
2 00000010 0 fjord
->  []
=== 1 / 00000001
0 00000000 1 foo
1 00000001 0 bar
2 00000010 0 fjord
->  ['foo']
=== 2 / 00000010
0 00000000 0 foo
1 00000001 1 bar
2 00000010 0 fjord
->  ['bar']
=== 3 / 00000011
0 00000000 1 foo
1 00000001 1 bar
2 00000010 0 fjord
->  ['foo', 'bar']
=== 4 / 00000100
0 00000000 0 foo
1 00000001 0 bar
2 00000010 1 fjord
->  ['fjord']
=== 5 / 00000101
0 00000000 1 foo
1 00000001 0 bar
2 00000010 1 fjord
->  ['foo', 'fjord']
=== 6 / 00000110
0 00000000 0 foo
1 00000001 1 bar
2 00000010 1 fjord
->  ['bar', 'fjord']
=== 7 / 00000111
0 00000000 1 foo
1 00000001 1 bar
2 00000010 1 fjord
->  ['foo', 'bar', 'fjord']
© www.soinside.com 2019 - 2024. All rights reserved.