我有两个测试结果列表。测试结果表示为词典:
list1 = [{testclass='classname', testname='testname', testtime='...},...]
list2 = [{testclass='classname', testname='testname', ...},...]
两个列表中的字典表示略有不同,因为对于一个列表,我有一些 更多信息。但在所有情况下,任一列表中的每个测试字典都将具有classname和testname元素,这些元素有效地形成了一种唯一标识测试的方式,以及一种在列表中进行比较的方法。
我需要找出list1中但不在list2中的所有测试,因为它们代表了新的测试失败。
要做到这一点我做:
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;
我想知道这是一种更加蟒蛇化的方式。我看过滤器。过滤器使用的函数需要获取两个列表的句柄。一个很容易,但我不确定如何处理这两个问题。我知道列表的内容直到运行时。
任何帮助将不胜感激,
感谢。
答案 0 :(得分:8)
试试这个:
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]
答案 1 :(得分:2)
如果classname
和testname
的每个组合确实是唯一的,那么计算效率更高的方法是使用两个词典而不是两个列表。作为字典的关键,使用像这样的元组:(classname, testname)
。然后你可以简单地说if (classname, testname) in d: ...
。
如果您需要保留插入顺序,并且使用的是Python 2.7或更高版本,则可以使用OrderedDict
模块中的collections
。
代码看起来像这样:
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]
如果由于某种原因必须使用列表,则可以迭代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]
答案 2 :(得分:2)
要比较其键的子集上的两个词典d1
和d2
,请使用:
all(d1[k] == d2[k] for k in ('testclass', 'testname'))
如果您的两个列表具有相同的长度,则可以使用zip()
将它们配对。