У меня есть список диктовок:
list = [{'id':'1234','name':'Jason'},
{'id':'2345','name':'Tom'},
{'id':'3456','name':'Art'}]
Как я могу эффективно найти позицию индекса [0], [1] или [2] путем сопоставления по name = 'Tom'?
Если бы это был одномерный список, я мог бы выполнить list.index (), но я не уверен, как действовать дальше, выполняя поиск значений dicts в списке.
{ 'Jason': {'id': '1234'}, 'Tom': {'id': '1245'}, ...}
?){'1234': {'name': 'Jason'}, ...}
. Не то, чтобы это помогло этому варианту использования.Ответы:
Если вам нужно многократно выполнять выборку по имени, вы должны проиндексировать их по имени (используя словарь), таким образом, операции получения будут выполняться за O (1) раз. Идея:
источник
next()
для этого кажется мне странным), цель - просто получить индекс. Кроме того, это вызывает StopIteration, тогда какlst.index()
метод Python вызывает ValueError.first()
звучит лучше. Вы всегда можете попробовать / кроме StopIteration и поднять ValueError, чтобы вызывающий абонент имел согласованность. В качестве альтернативы установитеnext()
значение по умолчанию на -1.SyntaxError: Generator expression must be parenthesized if not sole argument
когда это делаю.next((index for (index, d) in enumerate(lst) if d["name"] == "Tom"), None)
Простая читаемая версия
источник
str.find()
красиво имитирует поведение . Вы также можете вызвать егоindex()
и поднятьValueError
вместо возврата -1, если это предпочтительнее.Это не будет эффективно, так как вам нужно пройти по списку, проверяя каждый элемент в нем (O (n)). Если вам нужна эффективность, вы можете использовать dict of dicts . Что касается вопроса, вот один из возможных способов его найти (хотя, если вы хотите придерживаться этой структуры данных, на самом деле более эффективно использовать генератор, как написал Брент Ньюи в комментариях; см. Также ответ Токланда):
источник
Вот функция, которая находит позицию индекса словаря, если она существует.
источник
Кажется наиболее логичным использовать комбинацию фильтр / индекс:
И если вы думаете, что совпадений может быть несколько:
источник
Ответ, предложенный @faham, является хорошим однострочным, но он не возвращает индекс в словарь, содержащий значение. Вместо этого он возвращает сам словарь. Вот простой способ получить: список индексов один или несколько, если их больше одного, или пустой список, если их нет:
Вывод:
Что мне нравится в этом подходе, так это то, что с помощью простого редактирования вы можете получить список индексов и словарей в виде кортежей. Это проблема, которую мне нужно было решить, и я нашел эти ответы. Далее я добавил повторяющееся значение в другой словарь, чтобы показать, как это работает:
Вывод:
Это решение находит все словари, содержащие слово «Том» в любом из их значений.
источник
Один лайнер!?
источник
Для данной итерации
more_itertools.locate
выдает позиции элементов, которые удовлетворяют предикату.more_itertools
- это сторонняя библиотека, которая реализует рецепты itertools среди других полезных инструментов.источник
источник