需要从列表中找到4个数字,其总和将等于给定的“sum _”
def find_four(nums, sum_):
if len(nums) < 4:
return
i = 0
i2 = 1
i3 = 2
i4 = 3
while True:
num_sum = nums[i] + nums[i2] + nums[i3] + nums[i4]
if num_sum == sum_:
return [nums[i], nums[i2], nums[i3], nums[i4]]
elif i == len(nums) - 4:
return
elif i2 == len(nums) - 3:
i += 1
elif i3 == len(nums) - 2:
i2 += 1
elif i4 == len(nums) - 1:
i3 += 1
elif i4 != len(nums):
i4 += 1
我的代码适用于某些列表,例如:
find_four([1, 1, 1, 5, 1, 5, 7], 10)
或
find_four([4, 6, 1, 4, 1, 6, 2], 13)
。
但它不适用于一些例如'
find_four([7, 5, 1, 4, 1, 6, 2], 11)
(需要打印7, 1, 1, 2
)
怎么了 ?? :(
答案 0 :(得分:5)
没有嵌套循环的原因。
import itertools
import operator as op
from functools import reduce
def find_N(nums, target, N=4):
for combo in list(itertools.combinations(nums, N)):
if reduce(op.add, combo) == target:
return combo
return []
>>> find_N([1,2,3,4,5,6,7,8], target=10)
(1, 2, 3, 4)
>>> find_N([1,2,3,4,5,6,7,8], target=10, N=3)
(1, 2, 7)
>>> find_N([1,2,3,4,5,6,7,8], target=10, N=2)
(2, 8)
观察:
sum
不是一个声音变量名称,因为它破坏了该名称的内置函数答案 1 :(得分:2)
你可能应该在处理它之前对nums
进行排序,然后就像你正在做的那样。
def find_four(nums, sum_):
if len(nums) < 4:
return
nums = sorted(nums) # Sort nums here
i = 0
i2 = 1
i3 = 2
i4 = 3
while True:
num_sum = nums[i] + nums[i2] + nums[i3] + nums[i4]
if num_sum == sum_:
return [nums[i], nums[i2], nums[i3], nums[i4]]
elif i == len(nums) - 4:
return
elif i2 == len(nums) - 3:
i += 1
elif i3 == len(nums) - 2:
i2 += 1
elif i4 == len(nums) - 1:
i3 += 1
elif i4 != len(nums):
i4 += 1
这将为7, 1, 1, 2
生成find_four([7, 5, 1, 4, 1, 6, 2], 11)
。请注意,不会保留数字的顺序。
答案 2 :(得分:1)
只需使用itertools.combinations
即可。下面的代码将返回总和等于sum_的所有对。我通过在参数中传递4个默认值来设置combinations
以获取4个数字。您可以通过更改目标来交替用于计算总和的数量。
import itertools
from itertools import combinations
def find_four(nums, sum_,target=4):
return([pair for pair in itertools.combinations(nums,target) if sum(pair) == sum_])
nums=[1,2,3,4,1,5,6,7,8,9,10,11,12]
示例: -
>>> find_four([1,2,3,4,1,5,6,7,8,9,10,11,12],10)
[(1, 2, 3, 4), (1, 2, 1, 6), (1, 3, 1, 5), (2, 3, 4, 1)]
>>>find_four([1,2,3,4,1,5,6,7,8,9,10,11,12],10,3)
[(1, 2, 7), (1, 3, 6), (1, 4, 5), (1, 1, 8), (2, 3, 5), (2, 1, 7), (3, 1, 6), (4, 1, 5)]
答案 3 :(得分:0)
使用4个循环
可以更简单def find_four(arr, sum_):
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
for t in range(j + 1, len(arr)):
for k in range(t + 1, len(arr)):
if arr[i] + arr[j] + arr[t] + arr[k] == sum_:
return [arr[i],arr[j],arr[t],arr[k]]
return []
<强>输入强>
find_four([1, 1, 1, 5, 1, 5, 7], 10)
find_four([4, 6, 1, 4, 1, 6, 2], 13)
find_four([7, 5, 1, 4, 1, 6, 2], 11)
<强>输出强>
[1, 1, 1, 7]
[4, 6, 1, 2]
[7, 1, 1, 2]
答案 4 :(得分:0)
我注意到问题中的每个数字集合都是包或 multiset ,而不是一组。也就是说,每个集合至少包含一个成员的重复。这保证是这种情况,计算所有多集合组合可以更合适,从而避免处理重复组合。
>>> from sympy.utilities.iterables import multiset_combinations
>>> def find_four(nums, sum_):
... for c in multiset_combinations(nums, 4):
... if sum(c) == sum_:
... return c
... return {}
...
>>> find_four([1, 1, 1, 5, 1, 5, 7], 10)
[1, 1, 1, 7]
>>> find_four([4, 6, 1, 4, 1, 6, 2], 13)
[1, 2, 4, 6]
>>> find_four([7, 5, 1, 4, 1, 6, 2], 11)
[1, 1, 2, 7]