将不同的操作集与 Python 中的数字列表相结合



假设我们在 Python 中有一个数字列表:

l = [50,10,20,30,40]

我想:

  1. 查看以不同顺序将数字与 + 和 - 组合的结果,

  2. 查找哪组 + 和 - 组合将提供最接近 0 的结果。

例如,假设我们有"一组"操作

s1 = [-,-,-,+]

那么如果我们将 S1 应用于 l,我们将得到

50-10-20-30+40 = 30

如果我们要申请

s2 = [+,+,-,-]

那么我们会有

50+10+20-30-40 = 10

(因此,在这种情况下,s2 是最佳选择,因为它最接近 0(

我能做些什么来解决这个问题?

要将算术运算符号转换为 python 函数,您可以使用dict它将符号与模块中的函数匹配operator

import operator
operations_map = {
"+": operator.add,
"-": operator.sub,
"*": operator.mul,
"/": operator.truediv
}

要处理整数和运算符的列表,您可以使用下一个函数:

def process(numbers, operations):
if len(numbers) - 1 != len(operations):
raise ValueError(f"There're {len(numbers)} numbers and {len(operations)} operations.")
result = numbers[0]
for i in range(1, len(numbers)):
if operations[i - 1] in operations_map:
result = operations_map[operations[i - 1]](result, numbers[i])
else:
raise ValueError(f""{operations[i - 1]}" is not valid operation.")
return result

用法:

process([50, 10, 20, 30, 40], ["+", "-", "+", "+"])

要查找结果最接近零的运算序列,您可以使用itertools.permutations()生成运算符的排列,并使用min()查找最小结果:

from itertools import permutations
def closest_to_zero(numbers, operations):
return min(
((process(numbers, current), tuple(current)) for current in permutations(operations)), 
key=lambda x: abs(x[0])
)
value, chain = closest_to_zero([50, 10, 20, 30, 40], ["+", "-", "+", "+"])

要从可能的运算符集中获取所有可能的组合,您可以使用itertools.product(),其中repeat参数将设置为len(numbers) - 1

from itertools import product
def closest_to_zero_patched(numbers, operations):
return min(
((process(numbers, current), tuple(current)) for current in
product(operations, repeat=len(numbers) - 1)),
key=lambda x: abs(x[0])
)
value, chain = closest_to_zero_patched([50, 10, 20, 30, 40], {"+", "-"})

如果你想要一个几乎一行的(不一定是最有效的(:

您可以使用Truefor+Falsefor-对运算符列表进行编码,并为l列表的第一个元素添加额外的True值(如果始终希望添加此元素(,以便您的s1 = [-,-,-,+]列表如下所示:

s1 = [True, False, False, False, True]

然后使用itertools包中的compress函数,您可以得到以下结果:

from itertools import compress
sum(compress(l, s1)) - sum(compress(l, [not i for i in s1]))

它首先对+的所有元素求和,然后减去与-相关的所有元素。

最新更新