首页 > 解决方案 > 在 Python 中比较对象时避免嵌套循环

问题描述

我得到了两段代码,它们是由不同的人在不同的时间编写的,并且都可以单独运行。比较这两段代码之间的输出是我的工作。我还需要检查某些字段是否有任何错误。

脚本 1 返回一个Script1Objects 列表,每个 s 都有自己的属性。类似地,脚本 2 返回一个Script2Objects 列表,这些 s 与 s 相似Script1Object但不相同。

我的代码是这样的:

script1_list = script1()
script2_list = script2()

for item1 in script1_list:
    for item2 in script2_list:
        if is_match(item1, item2):
            do_matching_action()
            break
        elif is_different_match(item1, item2):
            do_other_matching_action()
            break

    if is_bad(item1):
       do_error_action() 

其中is_match()匹配大约十个不同的属性。例如:

def is_match(item1, item2):
    return item1.name == item2.name and item1.ID == item2.number and item1.description.startswith(item2.desc)

并且is_different_match()is_bad()一组类似的检查。

这可以正常工作,但可能会很慢,尤其是当第一个列表可能有几十万个条目而第二个很容易有数千个条目时。代码也不是很模块化,所以我希望避免双for循环会提高代码的可扩展性。我想知道如何改进这个实现,因为我确信这并没有充分利用 Python 的特性。

标签: pythonloops

解决方案


鉴于匹配的对象必须具有相似的 id(IDinScript1Objectnumberin Script2Object),并假设script2_list项目都有唯一的 s,您可以使用字典number创建从number到对象的映射。然后,当您进行迭代时,您可以直接从字典中获取 a (无需遍历整个)。然后,您可以像以前一样在两个对象上调用每个匹配函数:Script2Objectnumberscript2_list

script1_list = script1()
script2_list = script2()
script2_dict = {obj.number: obj for obj in script2_list}

for item1 in script1_list:
    item2 = script2_dict.get(item1.ID, None)
    if item2 is None: 
        print('no item2 found for this id: ', item1.ID)
        # do something if there's no matching id
    if is_match(item1, item2):
        do_matching_action()
    elif is_different_match(item1, item2):
        do_other_matching_action()

    if is_bad(item1):
       do_error_action() 

推荐阅读