我有两个字典的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)
Run Code Online (Sandbox Code Playgroud)
性能不是真正的问题,因为它是一个一次性的脚本.
相当于你目前正在做的事情,但反过来说,是:
unmatched_items_10 = [d for d in entries10 if d not in entries9]
Run Code Online (Sandbox Code Playgroud)
虽然比编码方式更简洁,但它具有相同的性能问题:它需要与每个列表中的项目数成比例的时间.如果你感兴趣的长度大约是9或10(正如这些数字似乎表明的那样),没问题.
但对于大部分长度的列表中,您可以通过排序名单和他们"通过加强"获得更好的性能"并行"可以这么说(时间成正比,N log N其中N越长列表的长度).还有其他可能性(增加复杂性;-)即使这种更高级的方法不足以为您提供所需的性能.除非你表明你确实需要它以获得良好的性能,否则我将避免提出非常复杂的内容(在这种情况下,请提及每个列表的典型长度以及作为其项目的dicts的典型内容,因为当然这样"细节"是选择算法的关键考虑因素,这种算法在速度和简单性之间是一个很好的折衷方案.
编辑:OP编辑他的Q以显示他关心的内容,对于任何两个dicts d1和d2两个列表中的每一个,不是d1 == d2(是in操作员检查的),而是d1[a]==d2[a] and 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)]
Run Code Online (Sandbox Code Playgroud)
我已经改变了逻辑(至!=和or,根据De Morgan的定律),因为我们想要不匹配的dicts .但是,如果您愿意:
unmatched_items_10 = [d for d in entries10
if not any(d[a]==d1[a] and d[b]==d2[b] for d2 in entries9)]
Run Code Online (Sandbox Code Playgroud)
就个人而言,我不喜欢,if not any并且if not all出于文体方面的原因,但数学是无可挑剔的(通过维基百科页面称之为De Morgan法律的扩展,因为它any是一个存在量词和all通用量词,可以这么说;-).性能应该大致相当(但是,OP在评论中明确表示,在这项任务中,性能对他们来说并不是非常重要).