Как получить n-й элемент списка Python или значение по умолчанию, если оно недоступно - PullRequest
122 голосов
/ 22 марта 2010

Я ищу в python эквивалент dictionary.get(key, default) для списков. Есть ли какая-нибудь идиома для получения n-го элемента списка или значения по умолчанию, если оно недоступно?

Например, учитывая список myList, я бы хотел получить myList[0] или 5, если myList - пустой список.

Спасибо.

Ответы [ 8 ]

104 голосов
/ 22 марта 2010
l[index] if index < len(l) else default

Для поддержки отрицательных индексов мы можем использовать:

l[index] if -len(l) <= index < len(l) else default
46 голосов
/ 22 марта 2010
try:
   a = b[n]
except IndexError:
   a = default

Редактировать: я удалил проверку для TypeError - возможно, лучше позволить вызывающей стороне справиться с этим.

26 голосов
/ 22 марта 2010
(a[n:]+[default])[0]

Это, вероятно, лучше, так как a становится больше

(a[n:n+1]+[default])[0]

Это работает, потому что если a[n:] это пустой список, если n => len(a)

Вот пример того, как это работает с range(5)

>>> range(5)[3:4]
[3]
>>> range(5)[4:5]
[4]
>>> range(5)[5:6]
[]
>>> range(5)[6:7]
[]

И полное выражение

>>> (range(5)[3:4]+[999])[0]
3
>>> (range(5)[4:5]+[999])[0]
4
>>> (range(5)[5:6]+[999])[0]
999
>>> (range(5)[6:7]+[999])[0]
999
23 голосов
/ 04 апреля 2014

Просто обнаружил, что:

next(iter(myList), 5)

iter(l) возвращает итератор на myList, next() потребляет первый элемент итератора и вызывает ошибку StopIteration, за исключением случаев, когда вызывается со значением по умолчанию, как здесь, второй аргумент, 5

Это работает только тогда, когда вам нужен 1-й элемент, как в вашем примере, но не в тексте вашего вопроса, так что ...

Кроме того, ему не нужно создавать временные списки в памяти, и он работает для любого итеративного вида, даже если у него нет имени (см. Комментарий Сюн Чиамова к ответу Грущчи)

16 голосов
/ 22 марта 2010
(L[n:n+1] or [somedefault])[0]
4 голосов
/ 26 августа 2017

... ищет в python эквивалент dict.get(key, default) для списков

Существует рецептов itertools , которые делают это для общих итераций. Для удобства вы можете > pip install more_itertools и импортировать эту стороннюю библиотеку, которая реализует для вас такие рецепты:

Код

import more_itertools as mit


mit.nth([1, 2, 3], 0)
# 1    

mit.nth([], 0, 5)
# 5    

Detail

Вот реализация рецепта nth:

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(itertools.islice(iterable, n, None), default)

Как и dict.get(), этот инструмент возвращает значение по умолчанию для отсутствующих индексов. Это относится к общим итерациям:

mit.nth((0, 1, 2), 1)                                      # tuple
# 1

mit.nth(range(3), 1)                                       # range generator (py3)
# 1

mit.nth(iter([0, 1, 2]), 1)                                # list iterator 
# 1  
1 голос
/ 31 августа 2018

Использование Python 3.4 contextlib.suppress(exceptions) для создания getitem() метода, аналогичного getattr().

import contextlib

def getitem(iterable, index, default=None):
    """Return iterable[index] or default if IndexError is raised."""
    with contextlib.suppress(IndexError):
        return iterable[index]
    return default
1 голос
/ 27 апреля 2018

Комбинируя @ Joachim с вышеупомянутым, вы можете использовать

next(iter(my_list[index:]), default)

Примеры:

next(iter(range(10)[8:]), 11)
8
>>> next(iter(range(10)[12:]), 11)
11

Или, может быть, более ясно, но без len

my_list[index] if my_list[index:] else default
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...