Почему в списке нет безопасного метода get, такого как словарь?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
Почему в списке нет безопасного метода get, такого как словарь?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
l[10:11]
этого попросите срез: вместоl[10]
, например. () У подсписка будет нужный элемент, если он существует).get
. Это было бы эквивалентомl[i] if i < len(l) else default
, но более читабельным, более кратким и позволяющимi
быть выражением без необходимости пересчитывать егоNone
если он не существует. Было бы неплохо сказать,x = expensive().get(0, None)
чтобы мне не пришлось помещать бесполезный возврат дорогого во временную переменную.Ответы:
В конечном счете, он, вероятно, не имеет безопасного
.get
метода, потому что adict
является ассоциативной коллекцией (значения связаны с именами), где неэффективно проверять наличие ключа (и возвращать его значение), не вызывая исключения, в то время как это супер тривиально чтобы исключить доступ к элементам списка (так какlen
метод очень быстрый)..get
метод позволяет вам запрашивать значение, связанное с именем, а не напрямую обращаться к 37-му элементу в словаре (что будет больше похоже на то, что вы запрашиваете в своем списке).Конечно, вы можете легко реализовать это самостоятельно:
Вы могли бы даже добавить его в
__builtins__.list
конструктор__main__
, но это было бы менее распространенным изменением, так как большая часть кода не использует его. Если вы просто хотите использовать это со списками, созданными вашим собственным кодом, вы можете просто создать подклассlist
и добавитьget
метод.источник
list
.get
решает проблему, которой нет в списках - эффективный способ избежать исключений при получении данных, которые могут не существовать. Очень просто и очень эффективно знать, что такое действительный индекс списка, но нет особенно хорошего способа сделать это для ключевых значений в словаре.O(1)
. Сlen
точки зрения сложности это будет не так быстро, как проверка , но с точки зрения сложности они всеO(1)
. Правильный ответ - типичное использование / семантика ...dict
это только лучший вариант O (1), а не все случаи..get()
либо у вас есть проблемы в другом месте вашего кода (или среды). Смысл использования такого метода - читабельность кода. Техника «ванили» требует четыре строки кода в каждом месте, что нужно сделать. Метод.get()
требует только одного и может быть легко связан с последующими вызовами методов (напримерmy_list.get(2, '').uppercase()
).Это работает, если вы хотите первый элемент, как
my_list.get(0)
Я знаю, что это не совсем то, что вы просили, но это может помочь другим.
источник
next(iter(my_list[index:index+1]), 'fail')
Позволяет для любого индекса, а не только 0. Или меньше FP , но , возможно , более Pythonic, и почти наверняка более читаемым:my_list[index] if index < len(my_list) else 'fail'
.Возможно, потому что это не имело особого смысла для семантики списка. Тем не менее, вы можете легко создать свой собственный, используя подклассы.
источник
get
метод. Читаемость имеет значение. И читаемость страдает с каждым дополнительным ненужным классом. Просто используйтеtry / except
подход без создания подклассов.Вместо использования .get, использование как это должно быть хорошо для списков. Просто разница в использовании.
источник
.get
метод (за исключением того, что я не уверен, как бы вы объяснили, что означал индекс в этом случае или почему он никогда не будет работать).lst[i] if -len(lst) <= i < len(l) else 'fail'
Попробуй это:
источник
Кредиты для jose.angel.jimenez
Для фанатов "oneliner" ...
Если вам нужен первый элемент списка или если вы хотите использовать значение по умолчанию, если список пуст, попробуйте:
возвращается
a
и
возвращается
default
Примеры для других элементов ...
С отступлением по умолчанию ...
Протестировано с
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
источник
value, = liste[:1] or ('default',)
. Похоже, вам нужны скобки.Лучшее, что вы можете сделать, это преобразовать список в dict, а затем получить к нему доступ с помощью метода get:
источник
zip range len
можно было просто использоватьdict(enumerate(my_list))
Поэтому я провел еще несколько исследований по этому вопросу, и оказалось, что для этого нет ничего конкретного. Я был взволнован, когда нашел list.index (значение), он возвращает индекс указанного элемента, но нет ничего для получения значения по определенному индексу. Так что если вы не хотите использовать решение safe_list_get, которое я считаю довольно хорошим. Вот некоторые 1 линейные операторы if, которые могут выполнить работу за вас в зависимости от сценария:
Вы также можете использовать «Нет» вместо «Нет», что имеет больше смысла.
Также, если вы хотите просто получить первый или последний элемент в списке, это работает
Вы также можете превратить их в функции, но мне все равно понравилось решение исключений IndexError. Я экспериментировал с фиктивной версией
safe_list_get
решения и сделал ее немного проще (по умолчанию нет):Не тестировали, чтобы увидеть, что быстрее.
источник
list
, создавая его подклассы. Таким образом, конструктор может взятьlist
или что-нибудь, что ведет себя как список, а новый экземпляр ведет себя как alist
. См. Ответ Кита ниже, который должен быть принятым ИМХО.dict.get()
аналога для возврата значения по умолчанию из ссылки на индекс списка вместо необходимости отлавливатьIndexError
? Так что на самом деле речь идет о функции языка / библиотеки (а не ООП»). против контекста FP). Кроме того, вероятно, нужно квалифицировать ваше использование «pythonic» как, возможно, WWGD (поскольку его презрение к FP Python хорошо известно) и не обязательно просто удовлетворение PEP8 / 20.el = x[4] if len(x) == 4 else 'No'
- ты имеешь в видуlen(x) > 4
?x[4]
вне границ, еслиlen(x) == 4
.Словари для поиска. Имеет смысл спросить, существует ли запись или нет. Списки обычно повторяются. Часто спрашивают, существует ли L [10], а скорее, если длина L равна 11.
источник
Ваш сценарий использования в основном важен только для массивов и матриц фиксированной длины, чтобы вы знали, как долго они находятся перед этим. В этом случае вы, как правило, также создаете их, прежде чем вручную заполнять их None или 0, так что фактически любой индекс, который вы будете использовать, уже существует.
Вы могли бы сказать это: мне нужно .get () в словарях довольно часто. После десяти лет работы программистом на полную ставку, я не думаю, что мне когда-либо это нужно было в списке. :)
источник
'lalala' in url.split('/')[2:]
. Но проблема с вашим решением в том, что вы смотрите только на второй элемент. Что делать, если URL-адрес '/ monkeybonkey / lalala'? Вы получите,True
хотя URL-адрес недействителен.