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

时间:2011-05-24 10:23:01

标签: python dictionary

更新

再次问好。我的问题是,如何比较字典的值是否相等。关于我的词典的更多信息:

  • 键是会话号
  • 每个键的值都是嵌套列表 - > F.E.

    [[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 :将会话编号1的值与字典中其他会话编号的值进行比较

第2步:获取下一个会话编号,并将这些值与其他会话编号的其他值进行比较,依此类推 - 最后我们将每个会话编号值进行比较

第3步:将结果保存到列表f.e.     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(计数器在2.7工作)也许我有时会改为2.7。

4 个答案:

答案 0 :(得分: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

我还建议(再次,出于性能原因)将元组嵌套在列表中而不是列表中,如果您不打算在运行中更改它们。我在这里发布的代码将以任何一种方式工作,但如果值已经是元组,它会更快。

答案 1 :(得分: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 = 5b = 5ab将指向相同的整数对象。但是,如果你将它们设置为10 ^ 5,它们就不会。但我不知道限制在哪里,所以我不确定这是否适用于您的代码。

答案 2 :(得分:0)

>>> from collections import Counter
>>> D = {1:[[100,0],[22,1],[23,2]],
... 10:[[100,0],[232,0],[10,2],[11,2]],
... 22:[[5,2],[23,2]]}
>>> [k for k,v in Counter(tuple(j) for i in D.values() for j in i).items() if v>1]
[(23, 2), (100, 0)]

如果确实需要列表

>>> [list(k) for k,v in Counter(tuple(j) for i in D.values() for j in i).items() if v>1]
[[23, 2], [100, 0]]

答案 3 :(得分: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]]