在Python中比较同一字典中每个键的字典值
更新:
大家好,我又来了。我的问题是,怎么比较字典中的值是否相等。关于我的字典,更多信息如下:
- 键是会话编号
每个键的值是嵌套列表,比如:
[[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 个回答
可能还有更好更优化的方法来解决这个问题,但我会从这里开始讲解:
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
,那么 a
和 b
会指向同一个整数对象。但是,如果你把它们设置为,比如说,10^5,它们就不会指向同一个对象了。不过我不知道这个限制在哪里,所以不确定这是否适用于你的代码。
在编程中,很多时候我们需要处理一些数据,比如从一个地方获取数据,然后把它放到另一个地方。这个过程就像是搬家,把东西从一个箱子搬到另一个箱子。
有时候,我们会遇到一些问题,比如数据格式不对,或者数据不完整。这就像是你在搬家的时候发现有些东西坏了,或者少了一些东西。为了避免这些问题,我们需要提前检查数据,确保一切都正常。
在编程里,我们可以使用一些工具和方法来帮助我们检查和处理这些数据。这样可以让我们的程序运行得更顺利,就像搬家时提前做好准备一样。
总之,处理数据就像是搬家,提前做好准备和检查,可以让整个过程变得更简单、更顺利。
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]]
如果你的字典很长,建议使用集合,这样性能会更好(在列表中查找已经遇到的值会比较慢):
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
我还建议(同样是为了性能考虑)在列表中嵌套元组,而不是再用列表,如果你不打算动态改变它们。这里我发的代码无论哪种方式都能工作,但如果值已经是元组的话,速度会更快。