在词典列表中查找项目

时间:2018-09-13 18:19:48

标签: python

我有这个数据

data = [
    {
        'id': 'abcd738asdwe',
        'name': 'John',
        'mail': 'test@test.com',
    },
    {
        'id': 'ieow83janx',
        'name': 'Jane',
        'mail': 'test@foobar.com',
    }
]

id是唯一的,不可能有多个字典包含相同的id。

例如,我要获取ID为“ ieow83janx”的商品。

我当前的解决方案如下:

search_id = 'ieow83janx'
item = [x for x in data if x['id'] == search_id][0]

您认为这是解决方案,还是有人知道替代解决方案?

5 个答案:

答案 0 :(得分:2)

由于class BaseSerializer(Field): def __new__(cls, *args, **kwargs): # We override this method in order to automagically create # `ListSerializer` classes instead when `many=True` is set. if kwargs.pop('many', False): return cls.many_init(*args, **kwargs) return super(BaseSerializer, cls).__new__(cls, *args, **kwargs) @classmethod def many_init(cls, *args, **kwargs): """ This method implements the creation of a `ListSerializer` parent class when `many=True` is used. You can customize it if you need to control which keyword arguments are passed to the parent, and which are passed to the child. Note that we're over-cautious in passing most arguments to both parent and child classes in order to try to cover the general case. If you're overriding this method you'll probably want something much simpler, eg: @classmethod def many_init(cls, *args, **kwargs): kwargs['child'] = cls() return CustomListSerializer(*args, **kwargs) """ allow_empty = kwargs.pop('allow_empty', None) child_serializer = cls(*args, **kwargs) list_kwargs = { 'child': child_serializer, } if allow_empty is not None: list_kwargs['allow_empty'] = allow_empty list_kwargs.update({ key: value for key, value in kwargs.items() if key in LIST_SERIALIZER_KWARGS }) meta = getattr(cls, 'Meta', None) list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer) return list_serializer_class(*args, **list_kwargs) 是唯一的,因此您可以将项目存储在字典中以实现O(1)查找。

id

那你就可以做

lookup = {ele['id']: ele for ele in data}

获取

答案 1 :(得分:2)

如果要对该特定对象进行多次此类操作,我建议将其library(magrittr) library(googlesheets) suppressMessages(gs_auth(token = "...\\Documents\\googlesheets_token.rds", verbose = FALSE)) 转换为字典。

id

在这种情况下,此查找操作将花费您一定的时间* data = [ { 'id': 'abcd738asdwe', 'name': 'John', 'mail': 'test@test.com', }, { 'id': 'ieow83janx', 'name': 'Jane', 'mail': 'test@foobar.com', } ] data_dict = {item['id']: item for item in data} #=> {'ieow83janx': {'mail': 'test@foobar.com', 'id': 'ieow83janx', 'name': 'Jane'}, 'abcd738asdwe': {'mail': 'test@test.com', 'id': 'abcd738asdwe', 'name': 'John'}} data_dict['ieow83janx'] #=> {'mail': 'test@foobar.com', 'id': 'ieow83janx', 'name': 'Jane'} 而不是O(1)

答案 2 :(得分:1)

next内置函数(docs)怎么样:

>>> data = [
...     {
...         'id': 'abcd738asdwe',
...         'name': 'John',
...         'mail': 'test@test.com',
...     },
...     {
...         'id': 'ieow83janx',
...         'name': 'Jane',
...         'mail': 'test@foobar.com',
...     }
... ]
>>> search_id = 'ieow83janx'
>>> next(x for x in data if x['id'] == search_id)
{'id': 'ieow83janx', 'name': 'Jane', 'mail': 'test@foobar.com'}

编辑:

如果找不到匹配项,它将引发StopIteration,这是处理缺勤的一种好方法:

>>> search_id = 'does_not_exist'
>>> try:
...     next(x for x in data if x['id'] == search_id)
... except StopIteration:
...     print('Handled absence!')
... 
Handled absence!

答案 3 :(得分:0)

无需创建新词典或无需编写多行代码,您只需使用内置的filter函数即可懒惰地获取项目,而不在找到匹配项后进行检查。

next(filter(lambda d: d['id']==search_id, data))

应该很好。

答案 4 :(得分:0)

这不会实现您的目标吗?

for i in data:
    if i.get('id') == 'ieow83janx':
        print(i)
(xenial)vash@localhost:~/python$ python3.7 split.py 
{'id': 'ieow83janx', 'name': 'Jane', 'mail': 'test@foobar.com'}

使用理解力:

[i for i in data if i.get('id') == 'ieow83janx']