【问题标题】:Python - comparing lists of dictionaries using tuples - unexpected behaviour?Python - 使用元组比较字典列表 - 意外行为?
【发布时间】:2016-08-15 23:18:44
【问题描述】:

我一直在尝试比较两个字典列表,并在 list2 中找到不在 list1 中的新人的用户 ID。例如第一个列表:

list1 = [{"userid": "13451", "name": "james", "age": "24", "occupation": "doctor"}, {"userid": "94324""name": "john", "age": "33", "occupation": "pilot"}]

和第二个列表:

list2 = [{"userid": "13451", "name": "james", "age": "24", "occupation": "doctor"}, {"userid": "94324""name": "john", "age": "33", "occupation": "pilot"}, {"userid": "34892", "name": "daniel", "age": "64", "occupation": "chef"}]

想要的输出:

newpeople = ['34892']

这是我整理出来的:

list1tuple = ((d["userid"]) for d in list1)
list2tuple = ((d["userid"]) for d in list2)

newpeople = [t for t in list2tuple if t not in list1tuple]

这实际上似乎非常有效,尤其是考虑到我使用的列表可能包含超过 50,000 个字典。但是,这里的问题是:

如果它在 list2 中找到一个确实不在 list1 中的用户 ID,它会将其添加到 newpeople(根据需要),但随后也会将 list2 中出现的所有其他用户 ID 也添加到 newpeople.

因此,假设 list2 包含 600 个用户 ID,而 list2 中的第 500 个用户 ID 在 list1 中的任何地方都找不到,那么 newpeople 中的第一项将是第 500 个用户 ID(再次,根据需要),但随后是其他 100 个用户 ID在新的之后。

这让我非常困惑 - 我非常感谢任何帮助我了解为什么会发生这种情况的人。

【问题讨论】:

  • list1tuple 既不是元组也不是列表,它是一个生成器......这是你的问题
  • @donkopotamus 有趣的是,我实际上运行了 type(list1tuple) 并得到了生成器,这让我更加困惑。你介意指出我如何解决这个问题/实现我的目标吗?谢谢

标签: python list dictionary tuples


【解决方案1】:

目前您已将list1tuplelist2tuple 设置为:

list1tuple = ((d["userid"]) for d in list1)
list2tuple = ((d["userid"]) for d in list2)

这些是生成器,而不是列表(或元组),这意味着它们只能迭代一次,这会导致您的问题。

您可以将它们更改为列表:

list1tuple = [d["userid"] for d in list1]
list2tuple = [d["userid"] for d in list2]

这将允许您根据需要多次迭代它们。但更好的解决方案是简单地设置它们:

list1tuple = set(d["userid"] for d in list1)
list2tuple = set(d["userid"] for d in list2)

然后取集合差

newpeople = list2tuple - list1tuple

【讨论】:

  • 有道理,谢谢!问题:这不是list1tuple/list2tuple中的附加括号吗?
【解决方案2】:

从 python 控制台可以看出,list1tuple 和 list2tuple 是生成器:

>>> ((d["userid"]) for d in list1)
<generator object <genexpr> at 0x10a9936e0>

虽然第二个可以保持为生成器(无需扩展列表),但第一个应先转换为列表、集合或元组,例如:

list1set = {d['userid'] for d in list1}
list2generator = (d['userid'] for d in list2)

您现在可以检查该组的成员资格:

>>> [t for t in list2generator if t not in list1set]
['34892']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多