问题:通过匹配字典的值来找到列表中字典的索引
我有一些字典:
list = [{'id':'1234','name':'Jason'},
{'id':'2345','name':'Tom'},
{'id':'3456','name':'Art'}]
如何通过匹配name =’Tom’来有效地找到索引位置[0],[1]或[2]?
如果这是一维列表,则可以执行list.index(),但是我不确定如何通过搜索列表中的dict的值来进行操作。
回答 0
tom_index = next((index for (index, d) in enumerate(lst) if d["name"] == "Tom"), None)
# 1
如果需要从名称重复获取,则应按名称对它们进行索引(使用字典),这样get操作的时间为O(1)。一个想法:
def build_dict(seq, key):
return dict((d[key], dict(d, index=index)) for (index, d) in enumerate(seq))
info_by_name = build_dict(lst, key="name")
tom_info = info_by_name.get("Tom")
# {'index': 1, 'id': '2345', 'name': 'Tom'}
回答 1
一个简单的可读版本是
def find(lst, key, value):
for i, dic in enumerate(lst):
if dic[key] == value:
return i
return -1
回答 2
效率不高,因为您需要遍历列表检查其中的每个项目(O(n))。如果要提高效率,可以使用dict of dicts。关于这个问题,这是找到它的一种可能方法(不过,如果您要坚持使用这种数据结构,实际上使用 Brent Newey在评论中所写的生成器会更有效;另请参阅tokland的答案):
>>> L = [{'id':'1234','name':'Jason'},
... {'id':'2345','name':'Tom'},
... {'id':'3456','name':'Art'}]
>>> [i for i,_ in enumerate(L) if _['name'] == 'Tom'][0]
1
回答 3
这是一个查找字典索引位置(如果存在)的函数。
dicts = [{'id':'1234','name':'Jason'},
{'id':'2345','name':'Tom'},
{'id':'3456','name':'Art'}]
def find_index(dicts, key, value):
class Null: pass
for i, d in enumerate(dicts):
if d.get(key, Null) == value:
return i
else:
raise ValueError('no dict with the key and value combination found')
print find_index(dicts, 'name', 'Tom')
# 1
find_index(dicts, 'name', 'Ensnare')
# ValueError: no dict with the key and value combination found
回答 4
似乎最合乎逻辑的是使用过滤器/索引组合:
names=[{}, {'name': 'Tom'},{'name': 'Tony'}]
names.index(filter(lambda n: n.get('name') == 'Tom', names)[0])
1
如果您认为可能存在多个匹配项:
[names.index(n) for item in filter(lambda n: n.get('name') == 'Tom', names)]
[1]
回答 5
@faham提供的答案很不错,但是它不会将索引返回包含该值的字典。而是返回字典本身。这是一种简单的获取方法:如果有多个索引,则一个或多个索引列表;如果不存在,则为空列表:
list = [{'id':'1234','name':'Jason'},
{'id':'2345','name':'Tom'},
{'id':'3456','name':'Art'}]
[i for i, d in enumerate(list) if 'Tom' in d.values()]
输出:
>>> [1]
我喜欢这种方法的地方是,通过简单的编辑,您既可以将索引又将字典作为元组得到一个列表。这是我需要解决并找到这些答案的问题。在下面的代码中,我在另一个字典中添加了重复的值以显示其工作方式:
list = [{'id':'1234','name':'Jason'},
{'id':'2345','name':'Tom'},
{'id':'3456','name':'Art'},
{'id':'4567','name':'Tom'}]
[(i, d) for i, d in enumerate(list) if 'Tom' in d.values()]
输出:
>>> [(1, {'id': '2345', 'name': 'Tom'}), (3, {'id': '4567', 'name': 'Tom'})]
该解决方案可查找所有值中包含“ Tom”的所有词典。
回答 6
一行代码!!
elm = ([i for i in mylist if i['name'] == 'Tom'] or [None])[0]
回答 7
对于给定的可迭代项,more_itertools.locate
产生满足谓词的项的位置。
import more_itertools as mit
iterable = [
{"id": "1234", "name": "Jason"},
{"id": "2345", "name": "Tom"},
{"id": "3456", "name": "Art"}
]
list(mit.locate(iterable, pred=lambda d: d["name"] == "Tom"))
# [1]
more_itertools
是在其他有用工具中实现itertools配方的第三方库。
回答 8
def search(itemID,list):
return[i for i in list if i.itemID==itemID]
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。