首页 > 解决方案 > 查找所有加起来为特定目标值的唯一值

问题描述

是否有一种更 Pythonic 的方法来查找所有加起来为特定目标数字的数字组合(每个组合由唯一数字组成)。例如:

largest_single_number = 9  # in this example: single digits only
num_of_inputs = 5
target_sum = 30

# expected output:

0 + 6 + 7 + 8 + 9 = 30
1 + 5 + 7 + 8 + 9 = 30
2 + 4 + 7 + 8 + 9 = 30
2 + 5 + 6 + 8 + 9 = 30
3 + 4 + 6 + 8 + 9 = 30
3 + 5 + 6 + 7 + 9 = 30
4 + 5 + 6 + 7 + 8 = 30

number of possibilities:  7

我们的代码如下所示:

counter = 0
largest_single_number = 9  # in this example: single digits only
num_of_inputs = 5  # Not used but dictates number of nested loops
target_sum = 30

for digit_1 in range(largest_single_number + 1):
    for digit_2 in range(digit_1 + 1, largest_single_number + 1):
        for digit_3 in range(digit_2 + 1, largest_single_number + 1):
            for digit_4 in range(digit_3 + 1, largest_single_number + 1):
                for digit_5 in range(digit_4 + 1, largest_single_number + 1):
                    if (
                        digi_sum := (digit_1 + digit_2 + digit_3 + digit_4 + digit_5)
                    ) == target_sum:
                        print(
                            f"{digit_1} + {digit_2} + {digit_3} + {digit_4} + {digit_5} = {target_sum}"
                        )
                        counter += 1
                    elif digi_sum > target_sum:
                        break

print("number of possibilities: ", counter)

我们将不胜感激知道什么是更 Pythonic 的方式来实现相同的结果。

标签: pythonpython-3.x

解决方案


采用itertools.combinations

from itertools import combinations

values = [x for x in combinations(range(10), 5) if sum(x) == 30]

print(len(values))
>>> 7

print(values)

[(0, 6, 7, 8, 9),
 (1, 5, 7, 8, 9),
 (2, 4, 7, 8, 9),
 (2, 5, 6, 8, 9),
 (3, 4, 6, 8, 9),
 (3, 5, 6, 7, 9),
 (4, 5, 6, 7, 8)]

获得预期的输出

for x in values:
    expected = ' + '.join(map(str, x)) + ' = 30'
    print(expected)

0 + 6 + 7 + 8 + 9 = 30
1 + 5 + 7 + 8 + 9 = 30
2 + 4 + 7 + 8 + 9 = 30
2 + 5 + 6 + 8 + 9 = 30
3 + 4 + 6 + 8 + 9 = 30
3 + 5 + 6 + 7 + 9 = 30
4 + 5 + 6 + 7 + 8 = 30

作为一个函数

def calculation(largest: int, number: int, target: int) -> list:
    values = [x for x in combinations(range(largest + 1), number) if sum(x) == target]
    print(f'number of possibilites: {len(values)}')

    for x in values:
        print(' + '.join(map(str, x)) + f' = {target}')


calculation(9, 5, 30)

number of possibilites: 7
0 + 6 + 7 + 8 + 9 = 30
1 + 5 + 7 + 8 + 9 = 30
2 + 4 + 7 + 8 + 9 = 30
2 + 5 + 6 + 8 + 9 = 30
3 + 4 + 6 + 8 + 9 = 30
3 + 5 + 6 + 7 + 9 = 30
4 + 5 + 6 + 7 + 8 = 30

推荐阅读