Find two numbers from a list that add up to a spec

2020-07-27 06:23发布

问题:

This is super bad and messy, I am new to this, please help me.

Basically, I was trying to find two numbers from a list that add up to a target number.

I have set up an example with lst = [2, 4, 6, 10] and a target value of target = 8. The answer in this example would be (2, 6) and (6, 2).

Below is my code but it is long and ugly and I am sure there is a better way of doing it. Can you please see how I can improve from my code below?

from itertools import product, permutations

numbers = [2, 4, 6, 10]
target_number = 8

two_nums = (list(permutations(numbers, 2)))
print(two_nums)

result1 = (two_nums[0][0] + two_nums[0][1])
result2 = (two_nums[1][0] + two_nums[1][1])
result3 = (two_nums[2][0] + two_nums[2][1])
result4 = (two_nums[3][0] + two_nums[3][1])
result5 = (two_nums[4][0] + two_nums[4][1])
result6 = (two_nums[5][0] + two_nums[5][1])
result7 = (two_nums[6][0] + two_nums[6][1])
result8 = (two_nums[7][0] + two_nums[7][1])
result9 = (two_nums[8][0] + two_nums[8][1])
result10 = (two_nums[9][0] + two_nums[9][1])

my_list = (result1, result2, result3, result4, result5, result6, result7, result8, result9, result10)
print (my_list)

for i in my_list:
  if i == 8:
print ("Here it is:" + str(i))

回答1:

For every number on the list, you can look for his complementary (number that when added to the previous one would give the required target sum). If it exists, get the pair and exit, otherwise move on.

This would look like the following:

numbers = [2, 4, 6, 10]
target_number = 8

for i, number in enumerate(numbers[:-1]):  # note 1
    complementary = target_number - number
    if complementary in numbers[i+1:]:  # note 2
        print("Solution Found: {} and {}".format(number, complementary))
        break
else:  # note 3
    print("No solutions exist")

which produces:

Solution Found: 2 and 6

Notes:

  1. You do not have to check the last number; if there was a pair you would have already found it by then.
  2. Notice that the membership check (which is quite costly in lists) is optimized since it considers the slice numbers[i+1:] only. The previous numbers have been checked already. A positive side-effect of the slicing is that the existence of one 4 in the list, does not give a pair for a target value of 8.
  3. This is an excellent setup to explain the miss-understood and often confusing use of else in for-loops. The else triggers only if the loop was not abruptly ended by a break.


If the 4 - 4 solution is acceptable to you even when having a single 4 in the list you can modify as follows:

numbers = [2, 4, 6, 10]
target_number = 8

for i, number in enumerate(numbers):
    complementary = target_number - number
    if complementary in numbers[i:]:
        print("Solution Found: {} and {}".format(number, complementary))
        break
else:
    print("No solutions exist")


回答2:

The simplest general way to do this is to iterate over your list and for each item iterate over the rest of the list to see if it adds up to the target value. The downside of this is it is an O(n^2) operation. I don't know off the top of my head if there is a more efficient solution. I'm not 100% sure my syntax is correct, but it should look something like the following:

done = False
for i, val in enumerate(numbers):
    if val >= target_number:
        continue
    for j, val2 in enumerate(numbers, i+1):
        if val + val2 == target_number:
            print ("Here it is: " + str(i) + "," + str(j))
            done = True
            break
    if done:
        break

Of course you should create this as a function that returns your result instead of just printing it. That would remove the need for the "done" variable.



回答3:

A list comprehension will work well here. Try this:

from itertools import permutations

numbers = [2, 4, 6, 10]
target_number = 8

solutions = [pair for pair in permutations(numbers, 2) if sum(pair) == 8]
print('Solutions:', solutions)

Basically, this list comprehension looks at all the pairs that permutations(numbers, 2) returns, but only keeps the ones whose total sum equals 8.



回答4:

If you are trying to find the answer for multiple integers with a long list that has duplicate values, I would recommend using frozenset. The "checked" answer will only get the first answer and then stop.

import numpy as np
numbers = np.random.randint(0, 100, 1000)
target = 17

def adds_to_target(base_list, target):
    return_list = []
    for i in range(len(base_list)):
        return_list.extend([list((base_list[i], b)) for b in base_list if (base_list[i] + b)==target])
    return set(map(frozenset, return_list))

# sample output
{frozenset({7, 10}),
 frozenset({4, 13}),
 frozenset({8, 9}),
 frozenset({5, 12}),
 frozenset({2, 15}),
 frozenset({3, 14}),
 frozenset({0, 17}),
 frozenset({1, 16}),
 frozenset({6, 11})}

1) In the first for loop, lists containing two integers that sum to the target value are added to "return_list" i.e. a list of lists is created.

2) Then frozenset takes out all duplicate pairs.

%timeit adds_to_target(numbers, target_number)
# 312 ms ± 8.86 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


回答5:

you can do it in one line with list comprehension like below:

from itertools import permutations

numbers = [2, 4, 6, 10]
target_number = 8
two_nums = (list(permutations(numbers, 2)))

result=[i for i in two_nums if i[0]+i[1] == target_number]

[(2,6) , (6,2)]



回答6:

If you want a way to do this efficiently without itertools -

numbers = [1,3,4,5,6,2,3,4,1]
target = 5
number_dict = {}
pairs = []
for num in numbers:
    number_dict[num] = number_dict.get(num, 0) + 1
    complement = target - num
    if complement in number_dict.keys():
        pairs.append((num, complement))
        number_dict.pop(num)
        number_dict.pop(complement)


回答7:

This is this simple :)

def func(array, target):
    flag = 0;
    for x in array:
        for y in array:
            if (target-x) == y and x != y:
                print(x,y)
                flag = 1
                break
        if flag ==1:
            break


回答8:

import pandas as pd

Filename = "D:\\python interview\\test.txt"
wordcount_dict = dict()
#input("Enter Filename:") 

list_ = [1,2,4,6,8]
num = 10

for number in list_:
    num_add = number
    for number_ in list_:
        if number_ + num_add == num and number_ != num_add :
            print(number_ , num_add)