Это супер плохо и грязно, я новичок в этом, пожалуйста, помогите мне.
В основном, я пытался найти два числа из списка, которые составляют целевой номер.
Я установил пример с 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))
Для каждого числа в списке вы можете искать его дополнительный (число, которое при добавлении к предыдущему дало бы требуемую target
сумму). Если он существует, получите пару и выйдите, иначе двигайтесь дальше.
Это будет выглядеть следующим образом:
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")
который производит:
Solution Found: 2 and 6
Заметки:
numbers[i+1:]
срезов numbers[i+1:]
. Предыдущие номера уже проверены. Положительным побочным эффектом разреза является то, что существование одного из 4
в списке не дает пары для целевого значения 8
.else
for
-loops. else
срабатывает только в том случае, если цикл не был внезапно завершен break
. Если 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")
Если вы пытаетесь найти ответ для нескольких целых чисел с длинным списком, который имеет повторяющиеся значения, я бы порекомендовал использовать 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) Затем заморозка вынимает все дубликаты пар.
%timeit adds_to_target(numbers, target_number)
# 312 ms ± 8.86 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Вы можете сделать это в одну строку с пониманием списка, как показано ниже:
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
solutions = [pair for pair in permutations(numbers, 2) if sum(pair) == 8]
print('Solutions:', solutions)
В принципе, это понимание списка рассматривает все пары, которые permutations(numbers, 2)
возвращаются, но сохраняют только те, общая сумма которых равна 8.
Простейший общий способ сделать это - перебрать ваш список и для каждого элемента перебрать всю оставшуюся часть списка, чтобы увидеть, добавляет ли он до целевого значения. Недостатком этого является операция O (n ^ 2). Я не знаю, с моей точки зрения, если есть более эффективное решение. Я не уверен на 100%, что мой синтаксис верен, но он должен выглядеть примерно так:
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
Конечно, вы должны создать это как функцию, которая возвращает ваш результат, а не просто его печать. Это устранило бы необходимость в "сделанной" переменной.
4
и4
будет решением в вашем примере?