【问题标题】:compare list of objects and list of dicts比较对象列表和字典列表
【发布时间】:2021-06-24 09:37:12
【问题描述】:

我是 Python 新手,我有两个解决方案可以解决我的问题,但我想知道这是正确的方法还是有更聪明的解决方案?

我有一个包含对象的列表和第二个包含字典的列表。 两者都包含名称。 我想比较两个列表中是否包含名称。

对象列表的类

class Person():
def __init__(self, name):
    self.name = name

为示例创建两个列表

i = 0
while i < 100:
    person_list.append(Person("test" + str(i)))
    i += 1

search_list = list()
i = 300
while i > 0:
    search_list.append({"name": "test" + str(i)})
    i -= 1

选项 a 对我来说似乎效率很低,因为它在 search_list 的每次迭代中都会遍历整个 person_list

for search in search_list:
    if [p for p in person_list if p.name == search["name"]]:
        print(search["name"] + " found")
    else:
        print(search["name"] + " not found")

我不想从 person_list 中删除某些内容以缩短迭代时间,因为我稍后会重用它。

选项 b 创建一个新列表,其中仅包含在此列表中搜索之前的名称

for search in search_list:
    if search["name"] in names:
        print(search["name"] + " found")
        names.remove(search["name"])
    else:
        print(search["name"] + " not found")

【问题讨论】:

    标签: python list dictionary object


    【解决方案1】:

    您的两种方法每次都必须扫描整个列表对(这就是 x in some_list 在循环中的 person_list 所做的)。

    我要做的是首先遍历名称列表,构建一个dict 名称到索引。

    from collections import defaultdict
    
    names_to_indices = defaultdict(list)
    
    for index, search in enumerate(search_list):
        names_to_indices[search["name"]].append(index)
    

    如果您不关心索引,可以使用 set 代替:

    distinct_names = set(map(lambda search: search["name"], search_list))
    

    这是对搜索列表的一次遍历,需要非常量的空间。

    然后,您可以遍历您的 Persons 列表,探索 dictset 的名称。这通常是一个恒定时间的操作。因此,对于与sort_list 中不同键的数量成正比的空间价格(如果您使用集合;否则它与条目数成正比,因为您将存储索引)您现在可以执行签入与person_list 中的条目数成正比的时间量(而不是与n * m 成正比的时间量)。

    【讨论】:

    • 因为我可以即时访问列表的键,所以我不必遍历整个列表,对吗?谢谢你的解释,特别是我的两个选项都是一样的。
    • 是的:像key in some_dictkey in some_set 这样的检查通常是一个常数时间操作。 You can read more about that here 和(针对特定于 Python 的上下文)here
    • 这是一种常用技术,但我找不到好的复制品。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    相关资源
    最近更新 更多