【问题标题】:Get Values from List of Dictionaries从字典列表中获取值
【发布时间】:2020-05-17 15:28:39
【问题描述】:
sample_dict = [{'id':123, 'name':'ABC', 'loc':'XYZ'}, {'id':456, 'name':'DEF', 'loc':'ZYX'}, {'id':789, 'name':'GHI', 'loc':'YZX'}]

我想从给定的字典列表中选择键的值( id 和 name )。

我想要类似这样的结果:

result = ({'id': [123, 456, 789]}, {'name': ['ABC', 'DEF', 'GHI']})

除了下面列出的之外,还有其他实现吗?我想以更高的内存效率和更少的时间来实现这一点,因为我有数百万数据要解压。我们可以通过operator.itemgetteritertools 实现这一目标吗?哪个内存效率更高,消耗的时间更少?

使用字典和列表组合

{'id':[i.get('id') for i in sample_dict]}

{'name':[i.get('name') for i in sample_dict]}

使用地图

{'id': list(map(lambda x: x.get('id'), sample_dict))}

{'name': list(map(lambda x: x.get('name'), sample_dict))}

【问题讨论】:

    标签: python python-3.x itertools


    【解决方案1】:

    一个更简单的方法是这样的:

    for i in range(len(sample_dict)):
        print(sample_dict[i]['id'])
    

    【讨论】:

    • 这如何回答问题以及更多sample_dict 是一个列表,上面的代码将导致 TypeError
    • 我们可以在字典理解中更好地处理这个问题
    【解决方案2】:
    new_arr = {str:list} 
    for each in sample_dict:
        for keys in each.keys():
            if keys not in new_arr.keys():
                new_arr[keys] = []
            new_arr[keys].append(each[keys])
    

    输出是{'id': [123, 456, 789], 'name': ['ABC', 'DEF', 'GHI'], 'loc': ['XYZ', 'ZYX', 'YZX']}

    【讨论】:

    • 这可以通过上面提到的字典理解技术更好地处理。
    【解决方案3】:

    首先,您似乎在模拟数据库。为什么不实际使用数据库?或者至少是熊猫?

    其次,没有办法“更有效”地迭代 1000 多个项目,因为无论如何你仍然必须迭代 1000 多个项目。是的,itertools 和 itemgetter 在每个项目的基础上可能会快得可以忽略不计,但如果您的问题是数据大小,那将无济于事。

    您必须迭代整个数据集;但是,您可以这样做一次,然后就拥有一个可重用的结构。如果您发现自己针对不同的查询多次遍历整个数据集,这可以消除所有重复的工作:

    from collections import defaultdict
    from pprint import pprint
    
    database = [
        {'id':123, 'name':'ABC', 'loc':'XYZ'}, 
        {'id':456, 'name':'DEF', 'loc':'ZYX'}, 
        {'id':789, 'name':'GHI', 'loc':'YZX'}]
    
    index = defaultdict(list)
    for row in database:
        for key in row:
            index[key].append(row[key])
    
    pprint(index)
    

    默认字典(,
    {'id': [123, 456, 789],
    'loc': ['XYZ', 'ZYX', 'YZX'],
    '名称': ['ABC', 'DEF', 'GHI']})

    【讨论】:

    • 在字典理解方式上运行 CProfile 花费了我 2008 次调用(列表的 Len * 两次)但是在您的方法上运行 CProfile 花费了我 3006 次调用(3 列 * List 的 Len)。有没有其他具体的定位方式。
    • 另外,你能告诉我这是否会消耗内存,因为我们将它存储在 defaultdict 中
    • 然后不要复制字典 - 只需使用完整索引。我复制它只是为了证明它有信息。它不应该更快地构建索引,它应该避免在以后重新使用它时做任何工作。它具有与原始结构和您请求的输出相同的数据,因此它使用了那么多内存。但是,如果将这些数据保存在内存中很困难,那么您确实需要使用数据库。
    • 有些事情你没有告诉我。你如何储存它? simple_dict 是否存在于内存中,还是生成器?
    • ... 因为如果您可以仅在该部分上完成工作,迭代器会更有意义。如果一次在内存中只有一个 sample_dict 列表中的对象,则内存没有任何问题,这就是迭代器的基本点。但是您最初的问题在开始时将所有数据都保存在内存中,并且将内存中的所有数据用于输出,因此您几乎已经将其设计为防止迭代器完成其工作。
    猜你喜欢
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多