Python 从一个列表中找出两个加起来就是一个特定数字的数字

Python 从一个列表中找出两个加起来就是一个特定数字的数字,python,for-loop,permutation,Python,For Loop,Permutation,这是超级糟糕和混乱,我是新手,请帮助我 基本上,我试着从一个列表中找出两个数字,加起来就是一个目标数字 我用lst=[2,4,6,10]和目标值target=8建立了一个示例。本例中的答案是(2,6)和(6,2) 下面是我的代码,但它又长又难看,我相信有更好的方法。你能看看我如何从下面的代码中改进吗 from itertools import product, permutations numbers = [2, 4, 6, 10] target_number = 8 two_nums =

这是超级糟糕和混乱,我是新手,请帮助我

基本上,我试着从一个列表中找出两个数字,加起来就是一个目标数字

我用
lst=[2,4,6,10]
和目标值
target=8
建立了一个示例。本例中的答案是
(2,6)
(6,2)

下面是我的代码,但它又长又难看,我相信有更好的方法。你能看看我如何从下面的代码中改进吗

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))

对于列表中的每一个数字,您都可以查找其补码(当添加到上一个数字时,将给出所需的
目标值
总和)。如果存在,则获取该对并退出,否则继续

如下所示:

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")
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
产生:

Solution Found: 2 and 6

注:

  • 您不必检查最后一个号码;如果有一双的话,那时你已经找到了
  • 请注意,成员资格检查(在列表中非常昂贵)是优化的,因为它只考虑切片
    number[i+1:://code>。之前的数字已经检查过了。切片的一个积极的副作用是,例如列表中存在一个
    4
    ,不会为目标值
    8
    提供一对
  • 这是一个很好的设置,可以解释
    for
    -循环中
    else
    用法不易理解且经常混淆。只有当循环没有因
    中断而突然结束时,
    else
    才会触发


  • 如果您可以接受例如
    4
    -
    4
    解决方案,即使列表中有一个单个
    4
    ,您也可以修改如下:

    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")
    

    对于列表中的每一个数字,您都可以查找其补码(当添加到上一个数字时,将给出所需的
    目标值
    总和)。如果存在,则获取该对并退出,否则继续

    如下所示:

    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")
    
    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
    
    产生:

    Solution Found: 2 and 6
    

    注:

  • 您不必检查最后一个号码;如果有一双的话,那时你已经找到了
  • 请注意,成员资格检查(在列表中非常昂贵)是优化的,因为它只考虑切片
    number[i+1:://code>。之前的数字已经检查过了。切片的一个积极的副作用是,例如列表中存在一个
    4
    ,不会为目标值
    8
    提供一对
  • 这是一个很好的设置,可以解释
    for
    -循环中
    else
    用法不易理解且经常混淆。只有当循环没有因
    中断而突然结束时,
    else
    才会触发


  • 如果您可以接受例如
    4
    -
    4
    解决方案,即使列表中有一个单个
    4
    ,您也可以修改如下:

    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")
    

    您可以在一行中完成,如下所示:

    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)]


    您可以在一行中完成,如下所示:

    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)]


    实现这一点的最简单的一般方法是遍历列表,对于每个项目,遍历列表的其余部分,查看它是否与目标值相加。缺点是它是一个O(n^2)操作。我不知道是否有更有效的解决办法。我不能100%确定我的语法是否正确,但它应该如下所示:

    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")
    
    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
    

    当然,您应该将其创建为返回结果的函数,而不仅仅是打印结果。这将消除对“done”变量的需要。

    实现这一点的最简单的一般方法是迭代列表,并对每个项目迭代列表的其余部分,以查看其总和是否达到目标值。缺点是它是一个O(n^2)操作。我不知道是否有更有效的解决办法。我不能100%确定我的语法是否正确,但它应该如下所示:

    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")
    
    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
    

    当然,您应该将其创建为返回结果的函数,而不仅仅是打印结果。这将消除对“done”变量的需要。

    列表理解在这里很有效。试试这个:

    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)
    

    基本上,这个列表理解会查看所有
    置换(数字,2)
    返回的对,但只保留总和等于8的对。

    列表理解在这里很有效。试试这个:

    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)
    

    基本上,此列表理解会查看所有
    置换(数字,2)
    返回的对,但只保留总和等于8的对。

    如果您试图找到具有重复值的长列表的多个整数的答案,我建议使用frozenset。“选中”答案将只得到第一个答案,然后停止

    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) 在第一个for循环中,将包含两个与目标值相加的整数的列表添加到“return_list”中,即创建列表列表

    2) 然后frozenset取出所有重复对

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

    如果您试图找到具有重复值的长列表的多个整数的答案,我建议使用frozenset。“选中”答案将只得到第一个答案,然后停止

    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) 在第一个for循环中,将包含两个与目标值相加的整数的列表添加到“return_list”中,即创建列表列表

    2) 然后frozenset取出所有重复对

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

    如果您想要一种不用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)
    

    如果您想要一种不用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)
    
    这很简单:)

    这很简单:)


    在您的示例中,
    4
    4
    会是一个解决方案吗?这不是更适合或论坛吗?@Ev.Kounis,是的,但在这种情况下,我尽量不按其编号添加。您的代码几乎完全针对问题。如果我们的名单