我od
类型为OrderedDict
。我想访问它最近添加的(键,值)对。 od.popitem(last = True)
会这样做,但也会删除我不想要的od
对。
这样做的好方法是什么?可以/应该这样做:
class MyOrderedDict(OrderedDict):
def last(self):
return next(reversed(self))
答案 0 :(得分:52)
使用next(reversed(od))
是访问最近添加的元素的完美方式。类OrderedDict
使用双向链表来实现字典项并实现__reversed__()
,因此该实现使您可以O(1)访问所需的元素。是否值得为这个简单的操作继承OrderedDict()
可能会受到质疑,但这种方法没有任何实际的错误。
答案 1 :(得分:14)
来自timeit的一点点魔力可以帮到这里......
from collections import OrderedDict
class MyOrderedDict1(OrderedDict):
def last(self):
k=next(reversed(self))
return (k,self[k])
class MyOrderedDict2(OrderedDict):
def last(self):
out=self.popitem()
self[out[0]]=out[1]
return out
class MyOrderedDict3(OrderedDict):
def last(self):
k=(list(self.keys()))[-1]
return (k,self[k])
if __name__ == "__main__":
from timeit import Timer
N=100
d1=MyOrderedDict1()
for i in range(N): d1[i]=i
print ("d1",d1.last())
d2=MyOrderedDict2()
for i in range(N): d2[i]=i
print ("d2",d2.last())
d3=MyOrderedDict3()
for i in range(N): d3[i]=i
print("d3",d3.last())
t=Timer("d1.last()",'from __main__ import d1')
print ("OrderedDict1",t.timeit())
t=Timer("d2.last()",'from __main__ import d2')
print ("OrderedDict2",t.timeit())
t=Timer("d3.last()",'from __main__ import d3')
print ("OrderedDict3",t.timeit())
结果:
d1 (99, 99)
d2 (99, 99)
d3 (99, 99)
OrderedDict1 1.159217119216919
OrderedDict2 3.3667118549346924
OrderedDict3 24.030261993408203
(在python3.2上测试,Ubuntu Linux)。
正如@SvenMarnach所指出的,与我烹饪的其他两种方式相比,你所描述的方法非常有效。
答案 2 :(得分:2)
你的想法没问题,但默认迭代器只在键上,所以你的例子只返回最后一个键。你真正想要的是:
class MyOrderedDict(OrderedDict):
def last(self):
return list(self.items())[-1]
根据需要提供(key, value)
对,而不仅仅是键。
请注意,在3.x之前版本的Python上,OrderedDict.items()
会返回一个列表,因此您不需要list()
调用,但更高版本会返回dictionary view object,所以你会的。
编辑:如评论中所述,更快的操作是:
class MyOrderedDict(OrderedDict):
def last(self):
key = next(reversed(self))
return (key, self[key])
虽然我必须承认我在代码中找到了这个丑陋的东西(我从不喜欢获取密钥然后执行x[key]
来单独获取值,我更喜欢获取(key, value)
元组) - 取决于速度和偏好的重要性,您可能希望选择以前的选项。
答案 3 :(得分:0)
上帝,我希望这是所有内置功能...
这里可以节省您宝贵的时间。在Python 3.7中测试。 od
是您的OrderedDict。
# Get first key
next(iter(od.keys()))
# Get last key
next(reversed(od.keys()))
# Get first value
od[next(iter(od.keys()))]
# Get last value
od[next(reversed(od.keys()))]
# Get first key-value tuple
next(iter(od.items()))
# Get last key-value tuple
next(reversed(od.items()))