Задний план
Учитывая некоторый случайный массив чисел вроде [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?
— Деньги
@ Динеро, да. Больше информации Вот.
— Марк