重复字母组合与列表重量的组合

时间:2017-12-07 08:15:02

标签: python python-2.7 combinations

我有四个不同重量的字母

letters = ['C', 'N', 'O', 'S']
weights_of_l = [1, 1, 2, 2]

我想获得weight = 2的字母组合。这封信可以重复选择,订单也不重要。结果可以是列表或数组或任何形式,但使用此组合

comb_w2 = ['CC','NN','NC','O','S']

此处CNweight = 1,因此合并两个字母weight = 2:可能的组合为'CC','NN','NC'

OS已经weight = 2,因此无法与其他字母合并。有没有计算这个的库?我看到了itertools,但它只给出了可能性的数量,而不是组合。

5 个答案:

答案 0 :(得分:1)

你的问题是partitioning(不容易的事)。 您可以使用this帖子为给定的体重生成所有可能的组合结果。然后,您可以删除包含您在weights_of_l中没有的密钥的密钥。最后,用字母代替数字,并为具有相同权重的字母创建排列。

答案 1 :(得分:1)

@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))

答案 2 :(得分:1)

我的答案最终与Turksarama非常相似。也就是说,如果您需要结果组合,则必须对字母进行排序并使用集合来删除重复项。我的方法更简洁,但需要使用函数调用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)))

答案 3 :(得分:0)

创建字母的所有组合并使用过滤功能删除组合权重不等于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或您需要的重量的字母,然后创建所有组合。

答案 4 :(得分:0)

请尝试以下代码:

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']

这可能不是最好的方法。