在Python中比较同一字典中每个键的字典值

1 投票
4 回答
8003 浏览
提问于 2025-04-16 18:14

更新:

大家好,我又来了。我的问题是,怎么比较字典中的值是否相等。关于我的字典,更多信息如下:

  • 键是会话编号
  • 每个键的值是嵌套列表,比如:

    [[1,0],[2,0],[3,1]]

  • 每个键的值的长度不一样,所以会话编号1的值可能比会话编号2的值多

  • 这里有一个示例字典:

order_session = {1:[[100,0],[22,1],[23,2]],10:[[100,0],[232,0],[10,2],[11,2]],22:[[5,2],[23,2],....], ... }

我的目标:

第一步:比较会话编号1的值和字典中其他所有会话编号的值是否相等

第二步:拿下一个会话编号,继续比较它的值和其他会话编号的值,以此类推——最后每个会话编号的值都比较过了

第三步:把结果保存到一个列表,比如: output = [[100,0],[23,2], ... ] 或者 output = [(100,0),(23,2), ... ]

  • 如果你能看到会话1和会话10的值对[100,0]是相同的,另外会话1和会话22的值对[23,2]也是相同的。

谢谢你们的帮助。

更新2

感谢大家的帮助和建议,把嵌套的列表转换成元组列表,这样处理起来更方便。

我更喜欢Boaz Yaniv的解决方案;) 我也喜欢使用collections.Counter(),可惜我用的是2.6.4(Counter在2.7中才有效),也许我会在某个时候升级到2.7。

4 个回答

0

可能还有更好更优化的方法来解决这个问题,但我会从这里开始讲解:

seen = []
output = []

for val in order_session.values():
    for vp in val:
        if vp in seen:
            if not vp in output:
                output.append(vp)
        else:
            seen.append(vp)

print(output)

基本上,这段代码的作用是查看所有的值,如果某个值之前出现过,但还没有被输出过,就把它加到输出结果里。

需要注意的是,这个方法是针对实际的进行操作的。如果你有不同类型的对象,可能会导致指针的问题,我的算法可能会失效(我没有测试过,所以不太确定)。在Python中,对于“低”整数,它会重复使用相同的对象引用;也就是说,如果你先执行 a = 5 然后执行 b = 5,那么 ab 会指向同一个整数对象。但是,如果你把它们设置为,比如说,10^5,它们就不会指向同一个对象了。不过我不知道这个限制在哪里,所以不确定这是否适用于你的代码。

0

在编程中,很多时候我们需要处理一些数据,比如从一个地方获取数据,然后把它放到另一个地方。这个过程就像是搬家,把东西从一个箱子搬到另一个箱子。

有时候,我们会遇到一些问题,比如数据格式不对,或者数据不完整。这就像是你在搬家的时候发现有些东西坏了,或者少了一些东西。为了避免这些问题,我们需要提前检查数据,确保一切都正常。

在编程里,我们可以使用一些工具和方法来帮助我们检查和处理这些数据。这样可以让我们的程序运行得更顺利,就像搬家时提前做好准备一样。

总之,处理数据就像是搬家,提前做好准备和检查,可以让整个过程变得更简单、更顺利。

order_session = {1:[[100,0],[22,1],[23,2]],10:[[100,0],[232,0],[10,2],[11,2]],22:[[5,2],[23,2],[80,21]],}
output = []
for pair in sum(order_session.values(), []):
    if sum(order_session.values(), []).count(pair) > 1 and pair not in output:
        output.append(pair)

print output
...
[[100, 0], [23, 2]]
2

如果你的字典很长,建议使用集合,这样性能会更好(在列表中查找已经遇到的值会比较慢):

def get_repeated_values(sessions):
    known = set()
    already_repeated = set()
    for lst in sessions.itervalues():
        session_set = set(tuple(x) for x in lst)
        repeated = (known & session_set) - already_repeated
        already_repeated |= repeated
        known |= session_set
        for val in repeated:
            yield val

sessions = {1:[[100,0],[22,1],[23,2]],10:[[100,0],[232,0],[10,2],[11,2]],22:[[5,2],[23,2]]}
for x in get_repeated_values(sessions):
    print x

我还建议(同样是为了性能考虑)在列表中嵌套元组,而不是再用列表,如果你不打算动态改变它们。这里我发的代码无论哪种方式都能工作,但如果值已经是元组的话,速度会更快。

撰写回答