![](/img/trans.png)
[英]How to get all mathematical combinations of a list that equal a result number in Python
[英]How to get all combinations of n binary values where number of 1's are equal to or more than the number of 0's?
我想找到 0 和 1 的所有可能組合的列表。 唯一的條件是 1 的數量必須大於或等於 0 的數量。 例如,對於n = 4
4,output 應該是這樣的:
[(0, 0, 1, 1), (0, 1, 0, 1), (0, 1, 1, 0), (0, 1, 1, 1), (1, 0, 0, 1), (1, 0, 1, 0), (1, 0, 1, 1), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 1, 0), (1, 1, 1, 1)]
有沒有一種優雅的方法可以做到這一點?
您可以使用distinct_permutations
:
from more_itertools import distinct_permutations
def get_combos(n):
for i in range((n+1)//2, n + 1):
for permutation in distinct_permutations([1] * i + [0] * (n - i), n):
yield permutation
print(list(get_combos(4)))
# [(0, 0, 1, 1), (0, 1, 0, 1), (0, 1, 1, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 1, 0, 0), (0, 1, 1, 1), (1, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0)]
在這里,我們簡單地考慮每個子列表的排列:
[0, 0, 1, 1]
[0, 1, 1, 1]
[1, 1, 1, 1]
請注意,對於大n
, yield
語句非常有用,因為您不會一次生成所有排列。
我們需要使用distinct_permutations
因為你只使用 1 和 0,所以常規排列會給你重復的元素。
如果你不想安裝另一個庫,你可以使用:
from itertools import permutations
def get_combos(n):
for i in range(n // 2 if n%2 == 0 else n//2 + 1, n):
for permutation in permutations([1] * i + [0] * (n - i), n):
yield permutation
print(set(get_combos(4)))
# {(0, 1, 0, 1), (0, 1, 1, 1), (1, 0, 1, 1), (1, 1, 0, 0), (1, 1, 1, 0), (0, 1, 1, 0), (1, 0, 1, 0), (1, 0, 0, 1), (1, 1, 0, 1), (0, 0, 1, 1)}
as set
將消除重復的元素,代價是需要一次處理整個排列集合(即,通過調用set
,您將立即使用整個生成器,而不是根據需要從中提取元素)。
可能不清楚為什么需要這些。 考慮這個列表:
[1, 2]
默認情況下,排列會告訴您此列表的所有排列都是
(1, 2)
和
(2, 1)
然而, permutations
不會檢查元素是什么或者它們是否重復,所以它只是像上面那樣執行交換,如果列表是
[1, 1]
你會回來的
[(1, 1), (1, 1)]
基於@Kraigolas 出色的答案,我們甚至可以通過構建一個包含n // 2
零 ( 0
) 和n
個一 ( 1
) 的初始列表來簡化整個過程。 然后,我們僅從該初始列表中獲得長度為n
的distinct permutations
因此,對於n = 4
,我們從以下列表中返回大小為 4 的不同排列: [0, 0, 1, 1, 1, 1]
from more_itertools import distinct_permutations
def get_combos(n):
return distinct_permutations([0] * (n // 2) + [1] * n, n)
print(list(get_combos(4)))
# [(0, 0, 1, 1), (0, 1, 0, 1), (0, 1, 1, 0), (0, 1, 1, 1), (1, 0, 0, 1), (1, 0, 1, 0), (1, 0, 1, 1), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 1, 0), (1, 1, 1, 1)]
您可以使用itertools.product
和過濾器(您至少保留其中的一半,所以不會那么浪費):
from itertools import product
def get_combos(n):
minimum = -(-n // 2)
return [p
for p in product([0, 1], repeat=n)
if sum(p) >= minimum]
print(get_combos(4))
(使用p.count(1)
可能更快。)
或者itertools.combinations
用於選擇 n 個索引中的 k 個設置為 0:
from itertools import combinations
def get_combos(n):
for k in range(n//2 + 1):
for indexes in combinations(range(n), k):
combo = [1] * n
for i in indexes:
combo[i] = 0
yield tuple(combo)
print(list(get_combos(4)))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.