![](/img/trans.png)
[英]How to get all possible combinations from a list in python allowing repetition
[英]Combinations with repetition of letters with weight from list
我有四個不同權重的字母
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
我想得到weight = 2
的字母組合。 字母可以反復選擇,順序並不重要。 結果可以是列表或數組或任何形式,但具有此組合
comb_w2 = ['CC','NN','NC','O','S']
這里C
和N
weight = 1
所以將兩個字母組合起來的weight = 2
:可能的組合是'CC','NN','NC'
O
和S
已經具有weight = 2
因此它不能與其他字母結合。 是否有用於計算此值的庫? 我看到了itertools
但它只給出了可能性的數量,而沒有給出組合的可能性。
@Sneha的回答很簡潔明了,但是如果您要使用很多組合,那么最好不要過多地創建組合。 此解決方案更長,但對於目標得分高的字母較長的列表,運行速度更快:
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
def get_combos(letters, weights, goal):
weighted_letters = list(zip(letters, weights))
combos = set()
def get_combos(letters, weight):
for letter, next_weight in weighted_letters:
total = weight + next_weight
if total == goal:
combos.add(''.join(sorted(letters + letter)))
elif total > goal:
pass
else:
get_combos(letters + letter, weight+next_weight)
get_combos('',0)
return combos
print(get_combos(letters, weights_of_l, 3))
編輯:我認為這可能會更快:
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
def get_combos(letters, weights, goal):
weighted_letters = sorted(zip(weights, letters))
combos = []
def get_combos(letters, weight, weighted_letters):
for i, (next_weight, letter) in enumerate(weighted_letters):
total = weight + next_weight
if total == goal:
combos.append(letters + letter)
elif total > goal:
return
else:
get_combos(letters+letter, weight+next_weight, weighted_letters[i:])
get_combos('',0,weighted_letters)
return combos
print(get_combos(letters, weights_of_l, 3))
我的答案最終與特克薩拉瑪的答案非常相似。 即,如果需要結果的組合,則必須對字母進行排序並使用一組字符來消除重復項。 我的方法更簡潔,但是需要通過函數調用來調用set()
。
letters = ['C', 'N', 'O', 'S']
weights = [1, 1, 2, 2]
items = list(zip(weights, letters))
def combinations(items, max_weight, weight=0, word=''):
if weight == max_weight:
yield ''.join(sorted(word))
items_allowed = [(w, l) for w, l in items if max_weight - weight >= w]
for w, l in items_allowed:
for result in combinations(items_allowed, max_weight, weight+w, word+l):
yield result
print(set(combinations(items, 2)))
創建字母的所有組合,並使用過濾器功能刪除組合權重不等於2的所有組合。
from itertools import combinations_with_replacement
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
y=dict(zip(letters,weights_of_l)) #Creates a dict of the two list letters
#and weights_of_l
print(list(map(lambda x:''.join(x),filter(lambda
x:y[x[0]]+y[x[1]]==2,combinations_with_replacement(letters,2)))))
或者,您可以首先過濾字母列表中的所有字母,以包括重量小於2或所需重量的字母,然后創建所有組合。
嘗試以下代碼:
def find_combinations(letter_list, weight_list, weignt_sum):
output_list = []
letter_weight_dict = dict(zip(letter_list,weight_list))
for key, val in letter_weight_dict.items():
for key1, val1 in letter_weight_dict.items():
if val+val1 == weignt_sum:
if (key + key1)[::-1] not in output_list:
output_list.append(key+key1)
if val == weignt_sum:
output_list.append(key)
return set(output_list)
letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]
combinations = find_combinations(letters, weights_of_l, 2)
print combinations
我得到以下輸出:
['CC','S','NN','CN','O']
這可能不是最好的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.