Python идиома для возврата первого элемента или нет?
Самый питонский подход - это то, что продемонстрировал самый голосующий голос, и это было первое, что пришло мне в голову, когда я прочитал вопрос. Вот как его использовать, во-первых, если в функцию передан, возможно, пустой список:
def get_first(l):
return l[0] if l else None
И если список возвращается из функции get_list
:
l = get_list()
return l[0] if l else None
Другие способы продемонстрировать это здесь, с объяснениями
for
Когда я начал пытаться придумать умные способы сделать это, это второе, о чем я подумал:
for item in get_list():
return item
Это предполагает, что функция заканчивается здесь, неявно возвращая None
, если get_list
возвращает пустой список. Приведенный ниже явный код в точности эквивалентен:
for item in get_list():
return item
return None
if some_list
Было также предложено следующее (я исправил неправильное имя переменной), в котором также используется неявное None
. Это было бы предпочтительнее вышеописанного, так как в нем используется логическая проверка вместо итерации, которая может не произойти. Это должно быть легче сразу понять, что происходит. Но если мы пишем для удобочитаемости и удобства обслуживания, нам также следует добавить в конце явное return None
:
some_list = get_list()
if some_list:
return some_list[0]
срез or [None]
и выбор нулевого индекса
Этот вопрос также входит в число самых популярных:
return (get_list()[:1] or [None])[0]
Срез не нужен, и создает дополнительный список из одного элемента в памяти. Следующее должно быть более производительным. Для объяснения, or
возвращает второй элемент, если первый - False
в логическом контексте, поэтому, если get_list
возвращает пустой список, выражение, содержащееся в скобках, вернет список с 'None', который затем быть доступным по индексу 0
:
return (get_list() or [None])[0]
Следующий использует тот факт, что и возвращает второй элемент, если первый - True
в логическом контексте, и поскольку он дважды ссылается на my_list, он не лучше троичного выражения (и технически не является однострочным) ):
my_list = get_list()
return (my_list and my_list[0]) or None
next
Тогда у нас есть следующее умное использование встроенных next
и iter
return next(iter(get_list()), None)
Для объяснения iter
возвращает итератор с методом .next
. (.__next__
в Python 3.) Затем встроенный next
вызывает этот метод .next
и, если итератор исчерпан, возвращает заданное нами значение по умолчанию: None
.
Избыточное троичное выражение (a if b else c
) и кружение назад
Было предложено следующее, но обратное было бы предпочтительнее, так как логика обычно лучше понимается в положительном, а не отрицательном. Поскольку get_list
вызывается дважды, если результат не запомнен каким-либо образом, это будет плохо работать:
return None if not get_list() else get_list()[0]
Лучше обратное:
return get_list()[0] if get_list() else None
Еще лучше, используйте локальную переменную, чтобы get_list
вызывался только один раз, и у вас сначала было рекомендовано решение Pythonic:
l = get_list()
return l[0] if l else None