Я ищу в Python эквивалент dictionary.get(key, default)
для списков. Есть ли какая-то одна идиома лайнера для получения n-го элемента списка или значения по умолчанию, если оно недоступно?
Например, учитывая список myList, который я хотел бы получить myList[0]
, или 5, если myList
это пустой список.
Спасибо.
index == -1000000
должен вернутьсяdefault
.x[index] if 0 <= index < len(x) else default
было бы лучше, если быindex
можно было когда-нибудь быть отрицательным.valid_index()
неверна. Отрицательные показатели являются законными в Python - это должно быть-len(l) <= index < len(l)
.try: a = b[n] except IndexError: a = default
Изменить: я удалил проверку TypeError - возможно, лучше позволить вызывающему обработать это.
источник
(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
источник
next(iter(lst[i:i+1]), default)
- просто еще одна запись в загадочном уродливом конкурсе однострочных.Только что обнаружил, что:
next(iter(myList), 5)
iter(l)
возвращает итераторmyList
,next()
потребляет первый элемент итератора и вызываетStopIteration
ошибку, кроме случаев, когда вызывается со значением по умолчанию, как в данном случае, второй аргумент,5
Это работает только тогда, когда вам нужен 1-й элемент, как в вашем примере, но не в тексте вашего вопроса, поэтому ...
Кроме того, ему не нужно создавать временные списки в памяти, и он работает для любого типа итераций, даже если у него нет имени (см. Комментарий Xiong Chiamiov к ответу gruszczy)
источник
next(iter(myList[n:n+1]), 5)
теперь он работает дляn
элемента th.try
Вариант не один вкладыш (ASK , запрашиваемый OP). Это работает только для списков, потому чтоmyList
это список, указанный OP (если быть точным, это что-то индексируемое). Создание копии в памяти здесь не требует больших затрат, потому что я создаю здесь список из одного (или ни одного) элемента. Конечно, это небольшие накладные расходы, но не стоит их упоминать, если вы не делаете это миллионы раз в цикле. Кстати, я думаю, что создание и перехватIndexError
исключения, вероятно, дороже.(L[n:n+1] or [somedefault])[0]
источник
[] or ...
сделал. Однако лично я бы просто использовал принятое решение, так как оно легко читается (для новичков). Конечно, если заключить его в «def» с комментарием, это в значительной степени не проблема.L[n] == False
илиL[n] == None
илиL[n] == []
или более глобально все, что оценивается как False?[False]
является истинным.myval = l[n:n+1] or [somedefault]
, сработает нормально?Есть рецепты itertools, которые делают это для общих итераций. Для удобства вы можете
> pip install more_itertools
импортировать и эту стороннюю библиотеку, которая реализует для вас такие рецепты:Код
import more_itertools as mit mit.nth([1, 2, 3], 0) # 1 mit.nth([], 0, 5) # 5
Деталь
Вот реализация
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
источник
Дешевое решение - действительно сделать диктант с перечислением и использовать
.get()
как обычно, напримерdict(enumerate(l)).get(7, my_default)
источник
Комбинируя @ Joachim с вышеперечисленным, вы можете использовать
Примеры:
next(iter(range(10)[8:]), 11) 8 >>> next(iter(range(10)[12:]), 11) 11
Или, может быть, более ясно, но без
len
my_list[index] if my_list[index:] else default
источник
Использование 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
источник
Прочитав ответы, я буду использовать:
(L[n:] or [somedefault])[0]
источник
(L[n:n+1] or [somedefault])[0]
(добавлено n + 1) вместо этого, потому чтоL[n:]
создает длинный список и копирует все элементы отn
до конца. Только чтобы потом получить только один элемент. ПокаL[n:n+1]
создает список максимум из 1 элемента.n
, и я не хочу вычислять ее дважды или вводить переменную. Мои списки короткие. - Также ответL[n:n+1]
уже предоставил Игнасио Васкес-Абрамс