[英]Prevent duplicates from itertools.permutations
我想使用 2 A 和 2 B 獲得 4 個字符串的所有唯一排列
from itertools import permutations
perm = permutations('AABB', 4)
for i in list(perm):
print(i)
這讓我
('A', 'A', 'B', 'B')
('A', 'A', 'B', 'B')
('A', 'B', 'A', 'B')
('A', 'B', 'B', 'A')
...
如您所見,我得到了重復項。 我想這是因為它認為第一名和第二名的 A 是不同的值,但對我來說 AABB 只是 1 個獨特的結果。
我可以通過將所有這些都放入一個集合中以擺脫重復來解決此結果,但我認為我只是使用錯誤的排列函數。
我如何使用排列函數來獲得所有獨特的排列,使用 2 A 和 2 B 而不會得到 dups?
在 itertools 中沒有直接的方法可以做到這一點。 permutations()
的文檔指出:
元素根據它們的位置而不是它們的值被視為唯一的。
這意味着盡管兩個A
看起來與您相等,但 itertools 將它們視為不相等,因為它們在原始字符串中具有不同的位置。
您想要的結果數稱為 4 個值的多項式系數,其中 2 個相等,另外 2 個相等。 您可以通過將自己的等效函數編碼為permutations
來獲得所需的內容,但這需要一段時間來編碼和調試。 (也許稱它為multinomial
,雖然這個詞指的是一個數字,而不是實際的列表。)一種更簡單的方法,可能在執行和內存使用上較慢,但在編程中要快得多,是使用permutations
和 Python 的set
來刪除重復項。 你可以這樣做:
from itertools import permutations
perm = permutations('AABB', 4)
for i in set(perm):
print(i)
這可能會導致打印輸出的順序不同。 如果要恢復原始順序,請使用sorted(set(perm))
,因為permutations
按字典順序返回(如果您的原始字符串按排序順序)。
您可以迭代set
或使用hashing
from itertools import permutations, combinations
perm = set(permutations('AABB', 4))
for i in <b>perm</b>:
print(i)
#Output
('A', 'A', 'B', 'B')
('A', 'B', 'A', 'B')
('A', 'B', 'B', 'A')
('B', 'A', 'A', 'B')
('B', 'B', 'A', 'A')
('B', 'A', 'B', 'A')
使用字典:
from itertools import permutations, combinations
dicta = {}
perm = permutations('AABB', 4)
for i in list(perm):
if i in dicta:
dicta[i] += 1
else:
dicta[i] = 1
print([i for i in dicta.keys()])
您應該使用more_itertools.distinct_permutations
來實現這一點。
from more_itertools import distinct_permutations as idp
for p in idp('ABB'):
print(p)
你說得非常對, itertools
將元素放在它們的positions
而不是它們的values
上 - 因此,它不支持刪除這些類型的重復......
我們從the documentation
指出:
元素根據它們的位置而不是它們的值被視為唯一的。 因此,如果輸入元素是唯一的,則每個排列中不會有重復值。
這給我們留下了兩個選擇,要么編寫自己的function
,要么轉換為set
而不是list
:
from itertools import permutations
perm = permutations('AABB', 4)
for i in set(perm):
print(i)
outputs
:
('A', 'B', 'B', 'A')
('B', 'A', 'B', 'A')
('B', 'B', 'A', 'A')
('A', 'B', 'A', 'B')
('A', 'A', 'B', 'B')
('B', 'A', 'A', 'B')
請注意,無需將set
轉換回list
,因為您可以iterate
set
上面的輸出沒有錯。首先了解排列是如何工作的。
s = "AA"
對於上面的字符串,排列將給出 2 個字符串。
AA and AA
上述兩個字符串是完全有效的,因為
1st 2nd
A A --->this is first output.
2nd 1st
A A ----> this is 2nd one.
排列所做的只是替換字符的位置。 不幸的是,它不檢查任何重復項。 要刪除重復項,您可以使用集合,因為集合不允許任何重復值。
myList = ["AA", "AB", "AA"]
set(myList)
output---> "AA", "AB"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.