我有两个 Python 字典列表,entries9
和 entries10
。我想比较项目并将联合项目写入名为 joint_items
的新列表。我还想将不匹配的项目保存到两个新列表中,unmatched_items_9
和 unmatched_items_10
。
这是我的代码。获取 joint_items
和 unmatched_items_9
(在外部列表中)非常简单:但是如何获取 unmatched_items_10
(在内部列表中)?
for counter, entry1 in enumerate(entries9):
match_found = False
for counter2,entry2 in enumerate(entries10):
if match_found:
continue
if entry1[a]==entry2[a] and entry1[b]==entry2[b]: # the dictionaries only have some keys in common, but we care about a and b
match_found = True
joint_item = entry1
joint_items.append(joint_item)
#entries10.remove(entry2) # Tried this originally, but realised it messes with the original list object!
if match_found:
continue
else:
unmatched_items_9.append(entry1)
性能并不是真正的问题,因为它是一次性脚本。
最佳答案
与您当前正在做的事情等价的是:
unmatched_items_10 = [d for d in entries10 if d not in entries9]
虽然比您的编码方式更简洁,但它具有相同的性能问题:它所花费的时间与每个列表中的项目数成正比。如果您感兴趣的长度大约是 9 或 10(正如这些数字似乎表明的那样),没问题。
但对于相当长的列表,您可以通过对列表进行排序并“并行”地“逐步执行”它们来获得更好的性能(时间与 N log N
成正比,其中 N
是较长列表的长度)。还有其他可能性(越来越复杂;-)即使这种更高级的方法也不足以让您获得所需的性能。我不会建议非常复杂的东西,除非你表明你确实需要它来获得良好的性能(在这种情况下,请提及每个列表的典型长度和字典的典型内容是他们的项目,因为这样的“细节”当然是选择算法的关键考虑因素,这些算法是速度和简单性之间的良好折衷)。
编辑:OP 编辑了他的 Q 以显示他关心的内容,对于任意两个字典 d1
和 d2
两个列表,不是 d1 == d2
(这是 in
运算符检查的内容),而是 d1[a]==d2[a] 和 d1 [b]==d2[b]
。在这种情况下,不能使用 in
运算符(好吧,不是没有一些时髦的包装,但这是一个在可行的情况下最好避免的复杂情况;-),但是 all
内置替换它轻而易举:
unmatched_items_10 = [d for d in entries10
if all(d[a]!=d1[a] or d[b]!=d2[b] for d2 in entries9)]
我已经切换了逻辑(到 !=
和 or
,根据 De Morgan's laws )因为我们想要不匹配的字典。但是,如果您愿意:
unmatched_items_10 = [d for d in entries10
if not any(d[a]==d1[a] and d[b]==d2[b] for d2 in entries9)]
就个人而言,出于风格原因,我不喜欢if not any
和if not all
,但数学是无可挑剔的(维基百科页面称之为 Extensions符合 De Morgan 定律,因为 any
是一个存在量词,而 all
是一个全称量词,可以这么说;-)。性能应该差不多(但是,OP 确实在评论中澄清了性能对他们在这个任务上不是很重要)。
关于比较两个列表并打印不匹配项的 Pythonic 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3526196/