Need to find 4 numbers from list which sum will be equal to given "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
My code works good with some lists like: find_four([1, 1, 1, 5, 1, 5, 7], 10)
or find_four([4, 6, 1, 4, 1, 6, 2], 13)
. But it don't work with some for example' find_four([7, 5, 1, 4, 1, 6, 2], 11)
(need to print 7, 1, 1, 2
) What is wrong ?? :(
There's no reason for nested loops.
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)
Observations:
sum
isn't a sound variable name as it clobbers the built-in function of that name You should probably sort nums
before processing it in chunks of 4, as you're doing.
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
This will produce for 7, 1, 1, 2
for find_four([7, 5, 1, 4, 1, 6, 2], 11)
. Note that the order of the numbers will not be preserved.
Simply use itertools.combinations
. Below code will return all pairs from which has summation equals to sum_. I am setting combinations
to take 4 numbers by passing 4 default in the argument. You can alternate amount of numbers used for calculating sum by changing target.
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]
example:-
>>> 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)]
You can do this simpler using 4 loops
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 []
Input
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)
Output
[1, 1, 1, 7]
[4, 6, 1, 2]
[7, 1, 1, 2]
I notice that each collection of numbers in the question is a bag or multiset , rather than a set. That is, each collection contains at least one repetition of one of its members. This guaranteed to be the case, it can be more appropriate to calculate all multiset combinations and thereby avoid processing repeated combinations.
>>> 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]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.