简体   繁体   English

比较两个字典列表

[英]Compare two lists of dictionaries

Say i have two lists of dictionaries:假设我有两个字典列表:

a=[{'name':'A','color':'1'},
   {'name':'B','color':'2'}]
b=[{'name':'A','color':'3'},
   {'name':'c','color':'1'}]

I need something like this:我需要这样的东西:

for i in a:
    if i['name'] is not existent in b['name']:
         do this.
    else:
        if i['color'] is < than the corresponding item in b list:
            do that.

I don't know how to fetch the element form the second list which causes the iteration to go on "else:".我不知道如何从导致迭代继续“else:”的第二个列表中获取元素。

I need to say that the first list is smaller(several hundred items) but the second one has several thousand dictionaries, each with about a hundred items- efficiency is very important.我需要说的是,第一个列表较小(几百个项目),但第二个列表有几千个字典,每个字典大约有一百个项目-效率非常重要。

I did think about making a list of all values for the key['name'] in both lists and compare that but it would mean iterating first time to make these lists and then reiterating over the lists in order to do this or do that.我确实考虑过为两个列表中的键 ['name'] 制作一个所有值的列表并进行比较,但这意味着第一次迭代以制作这些列表,然后重复列表以执行此操作或执行此操作。 Thanks in advance!提前致谢!

You absolutely want to do an iteration over b before you start.在开始之前,您绝对想对b进行迭代。 The only obvious alternative is to iterate over b for every item in a , which is obviously worse.唯一明显的办法是遍历b每个项目a ,这显然是雪上加霜。

b_dict = {x['name']: x for x in b}
for item in a:
    if item['name'] in b_dict:
        f(b_dict['name']) 
    else:
        pass  # whatever

You may be interested in the get() method of Python dictionaries, if you wish to avoid using in followed by immediately getting the element.如果您希望避免使用in后立即获取元素,您可能对 Python 字典的get()方法感兴趣。

You can use a hash table or something like this:您可以使用哈希表或类似的东西:

a=[{'name':'A','color':'1'},
   {'name':'B','color':'2'}]
b=[{'name':'A','color':'3'},
   {'name':'c','color':'1'}]

for item in a:
    mach = list(filter(lambda x: x['name'] == item['name'], b))
    if mach:
        if int(item['color']) > int(mach[0]['color']):
            do that
    else:
        do this

Dict in Python is a kind of hash table with amortized O(1) . Python 中的 Dict 是一种具有分摊 O(1) 的哈希表 Then you can change your code to this:然后您可以将代码更改为:

a=[{'name':'A','color':'1'},
   {'name':'B','color':'2'}]
b=[{'name':'A','color':'3'},
   {'name':'c','color':'1'}]

b_dict = {item['name']:item['color'] for item in b}
for item in a:
    if item['name'] in b_dict and int(item['color']) < int(b_dict[item['name']]):
        print 'do this'
    else:
        print 'do that'

First make an index:先做一个索引:

a=[{'name':'A','color':'1'},
   {'name':'B','color':'2'}]

b=[{'name':'A','color':'3'},
   {'name':'C','color':'1'}]

dic = {}
for i,item in enumerate(b):
    dic[item['name']] = i
# dic will be {'A':0,'C':1}
for item in a:
    if not item['name'] in dic:
        #do this
    else:
        if b[dic[item['name']]]['color'] > item['color']:
            #do that

Instead of making a list of values for both the lists, do it only for list B. And then change your if condition to不要为这两个列表制作一个值列表,只为列表 B 做一个。然后将你的 if 条件更改为

if i['name'] is not existent in names_in_b:

You will need to check the performance gain of this method, but with this solution, you will need just one iteration over B and then iteration over A follows.您将需要检查此方法的性能增益,但使用此解决方案,您只需要对 B 进行一次迭代,然后对 A 进行迭代。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM