Задний план
Учитывая некоторый случайный массив чисел вроде [3, 5, -4, 8, 11, 1, -1, 6] и целевое значение 10найдите в массиве два числа, равных целевому значению.
Код
def two_Number_Sum(array, target):
unique_number_set = set()
for num in array:
required_value = target - num
if required_value in unique_number_set:
return [num, required_value]
else:
unique_number_set.add(num)
return []
print(two_Number_Sum([3, 5, -4, 8, 11, 1, -1, 6], 10))
Мне интересно, могу ли я сделать этот ответ более питоническим. У меня нет опыта работы с Python, поэтому я часто пишу код, например, Java или другой язык, и я считаю, что будет хорошей практикой критиковать себя и писать код, более питонический, чтобы он стал естественным.
2 ответа
Несколько предложений:
- Именование:
arrayне является массивом, более подходящим именем может бытьnumbers. Такжеunique_number_setможет быть простоunique_numbers, название уже говорит о том, что дубликатов нет. - Ненужное еще: the
elseне требуется, поэтому его можно удалить. - Подсказки типа: @Linny уже указывал на это. Я добавляю, что если результат не нужно изменять, рассмотрите возможность возврата кортежа. Кроме того, он сообщает вызывающему, что результат будет содержать только два числа.
from typing import List, Tuple, Union
def two_number_sum(numbers: List[int], target: int) -> Union[Tuple[int, int], Tuple[()]]:
unique_numbers = set()
for num in numbers:
required_value = target - num
if required_value in unique_numbers:
return num, required_value
unique_numbers.add(num)
return ()
Спасибо @KellyBundy и @AJNeufeld за отзывы в комментариях.
Вы можете сделать это с помощью itertools.combinations. Большая часть кода Python, который вы увидите, — это просто умное использование встроенных функций и библиотек. Знакомство с ними значительно ускорит ваше изучение этого языка :).
import itertools
from typing import List
def two_number_sum_2(array: List[int], target: int) -> List[int]:
for x, y in itertools.combinations(array, 2):
if x + y == target:
return [x, y]
Он короче, чище и быстрее исходного кода (быстрее с небольшими наборами данных). Еще пара советов:
- Функции и переменные должны быть
snake_caseнеSnake_Caseили жеcamel_Snake_Case. - Добавьте подсказки типов, чтобы отобразить, какие типы вы принимаете в качестве параметров и какое значение вы возвращаете из функции.
Это помогает, и есть ли способ сделать его более питоническим без использования встроенных функций? Я думаю, что в типичном интервью нельзя использовать встроенные функции.
— Деньги
- 5
Зачем использовать
itertools.combinationsбыстрее, чем решение OP?— Марк
@Marc, возможно, это быстрее, если включить время программиста и время процессора …
— Тоби Спейт
- 1
Это очень распространенный вопрос на собеседовании, если вы ответите на него решением, которое генерирует все комбинации без веских оснований, это отразится плохо. Для большого ввода
O(N)от OP собирается превзойти этотO(N^2)решение.— Гленн ди-джей
@Marc Для тестов, которые я запускал, мое решение было быстрее, но я вижу, что с большими наборами данных мое решение значительно медленнее. Я оставлю этот ответ здесь, потому что он все еще может быть жизнеспособной альтернативой при работе с небольшими наборами данных.
— Линни

Ваш возвращаемый тип неверен.
()это неTuple[int,int]. Вам понадобитсяUnion[Tuple[int,int], Tuple[]]. Или вернутьсяNoneи использоватьOptional[Tuple[int,int]]. Или оставьте возвращаемый тип и вызовите исключение, если пара не может быть найдена.— AJNeufeld
@AJNeufeld спасибо, я обновил ответ.
— Марк
Просто любопытно, что означает «Союз»? Означает ли это, что возвращаемый тип может быть пустым кортежем или кортежем с int, int?
— Деньги
@ Динеро, да. Больше информации Вот.
— Марк