简体   繁体   English

比较字典列表

[英]Comparing lists of dictionaries

I have two lists of test results. 我有两个测试结果列表。 The test results are represented as dictionaries: 测试结果表示为词典:

list1 = [{testclass='classname', testname='testname', testtime='...},...]
list2 = [{testclass='classname', testname='testname', ...},...]

The dictionary representation is slightly different in both lists, because for one list I have some more information. 两个列表中的字典表示略有不同,因为对于一个列表,我有更多信息。 But in all cases, every test dictionary in either list will have a classname and testname element which together effectively form a way of uniquely identifying the test and a way to compare it across lists. 但在所有情况下,任一列表中的每个测试字典都将具有classname和testname元素,这些元素有效地形成了唯一标识测试的方式以及跨列表进行比较的方法。

I need to figure out all the tests that are in list1 but not in list2, as these represent new test failures. 我需要找出list1中但不在list2中的所有测试,因为这些测试代表了新的测试失败。

To do this I do: 要做到这一点,我做:

def get_new_failures(list1, list2):
    new_failures = []
    for test1 in list1:
        for test2 in list2:
            if test1['classname'] == test2['classname'] and \
                    test1['testname'] == test2['testname']:
                break; # Not new breakout of inner loop
        # Doesn't match anything must be new
        new_failures.append(test1);
    return new_failures;

I am wondering is a more python way of doing this. 我想知道这是一个更加蟒蛇的方式。 I looked at filters. 我看过滤器。 The function the filter uses would need to get a handle to both lists. 过滤器使用的函数需要获取两个列表的句柄。 One is easy, but I am not sure how it would get a handle to both. 一个很容易,但我不确定如何处理这两个问题。 I do know the contents of the lists until runtime. 我知道列表的内容直到运行时。

Any help would be appreciated, 任何帮助,将不胜感激,

Thanks. 谢谢。

Try this: 试试这个:

def get_new_failures(list1, list2):
    check = set([(d['classname'], d['testname']) for d in list2])
    return [d for d in list1 if (d['classname'], d['testname']) not in check]

If each combination of classname and testname is truly unique, then the more computationally efficient approach would be to use two dictionaries instead of two lists. 如果classnametestname每个组合都是真正唯一的,那么计算效率更高的方法是使用两个字典而不是两个列表。 As key to the dictionary, use a tuple like so: (classname, testname) . 作为字典的关键,使用像这样的元组:( (classname, testname) Then you can simply say if (classname, testname) in d: ... . 然后你可以简单地if (classname, testname) in d: ...说出if (classname, testname) in d: ...

If you need to preserve insertion order, and are using Python 2.7 or above, you could use an OrderedDict from the collections module. 如果您需要保留插入顺序,并且正在使用Python 2.7或更高版本,则可以使用collections模块中的OrderedDict

The code would look something like this: 代码看起来像这样:

tests1 = {('classname', 'testname'):{'testclass':'classname', 
                                     'testname':'testname',...}, 
         ...}
tests2 = {('classname', 'testname'):{'testclass':'classname', 
                                     'testname':'testname',...}, 
         ...}

new_failures = [t for t in tests1 if t not in tests2]

If you must use lists for some reason, you could iterate over list2 to generate a set, and then test for membership in that set: 如果由于某种原因必须使用列表,则可以迭代list2以生成集合,然后测试该集合中的成员资格:

test1_tuples = ((d['classname'], d['testname']) for d in test1)
test2_tuples = set((d['classname'], d['testname']) for d in test2)
new_failures = [t for t in test1_tuples if t not in test2_tuples]

To compare two dict d1 and d2 on a subset of their keys, use: 要比较其键的子集上的两个dict d1d2 ,请使用:

all(d1[k] == d2[k] for k in ('testclass', 'testname'))

And if your two list have the same lenght, you can use zip() to pair them. 如果你的两个列表具有相同的长度,你可以使用zip()来配对它们。

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

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