问题描述
我有这个
d1 = OrderedDict([('a', '1'), ('b', '2')])
如果我这样做
d1.update({'c':'3'})
然后我得到这个
OrderedDict([('a','1'),('b','2'),('c' 3')])
但我想要这个
[('c', '3'), ('a', '1'), ('b', '2')]
没有创建新字典
推荐答案
没有内置的方法在Python中执行此操作2.如果需要,您需要编写一个 prepend()
方法/函数,它在 OrderedDict
具有O(1)复杂性的内部元素。
There's no built-in method for doing this in Python 2. If you need this, you need to write a prepend()
method/function that operates on the OrderedDict
internals with O(1) complexity.
对于Python 3.2及更高版本,您可以使用 方法。该方法接受最后一个
参数,该参数指示元素是否将被移动到底部( last = True
)或 OrderedDict
的顶部( last = False
)
For Python 3.2 and later, you can use the move_to_end
method. The method accepts a last
argument which indicates whether the element will be moved to the bottom (last=True
) or the top (last=False
) of the OrderedDict
.
最后,如果你想要一个快速,肮脏和缓慢的解决方案,你可以从头创建一个新的 OrderedDict
。
Finally, if you want a quick, dirty and slow solution, you can just create a new OrderedDict
from scratch.
四种不同解决方案的详细信息:
Details for the four different solutions:
from collections import OrderedDict
class MyOrderedDict(OrderedDict):
def prepend(self, key, value, dict_setitem=dict.__setitem__):
root = self._OrderedDict__root
first = root[1]
if key in self:
link = self._OrderedDict__map[key]
link_prev, link_next, _ = link
link_prev[1] = link_next
link_next[0] = link_prev
link[0] = root
link[1] = first
root[1] = first[0] = link
else:
root[1] = first[0] = self._OrderedDict__map[key] = [root, first, key]
dict_setitem(self, key, value)
演示:
>>> d = MyOrderedDict([('a', '1'), ('b', '2')])
>>> d
MyOrderedDict([('a', '1'), ('b', '2')])
>>> d.prepend('c', 100)
>>> d
MyOrderedDict([('c', 100), ('a', '1'), ('b', '2')])
>>> d.prepend('a', d['a'])
>>> d
MyOrderedDict([('a', '1'), ('c', 100), ('b', '2')])
>>> d.prepend('d', 200)
>>> d
MyOrderedDict([('d', 200), ('a', '1'), ('c', 100), ('b', '2')])
操作 OrderedDict $ c的独立功能$ c> objects
此函数通过接受dict对象,键值和值来做同样的事情。我个人更喜欢类:
Standalone function that manipulates OrderedDict
objects
This function does the same thing by accepting the dict object, key and value. I personally prefer the class:
from collections import OrderedDict
def ordered_dict_prepend(dct, key, value, dict_setitem=dict.__setitem__):
root = dct._OrderedDict__root
first = root[1]
if key in dct:
link = dct._OrderedDict__map[key]
link_prev, link_next, _ = link
link_prev[1] = link_next
link_next[0] = link_prev
link[0] = root
link[1] = first
root[1] = first[0] = link
else:
root[1] = first[0] = dct._OrderedDict__map[key] = [root, first, key]
dict_setitem(dct, key, value)
演示: strong>
Demo:
>>> d = OrderedDict([('a', '1'), ('b', '2')])
>>> ordered_dict_prepend(d, 'c', 100)
>>> d
OrderedDict([('c', 100), ('a', '1'), ('b', '2')])
>>> ordered_dict_prepend(d, 'a', d['a'])
>>> d
OrderedDict([('a', '1'), ('c', 100), ('b', '2')])
>>> ordered_dict_prepend(d, 'd', 500)
>>> d
OrderedDict([('d', 500), ('a', '1'), ('c', 100), ('b', '2')])
使用 OrderedDict.move_to_end()
(Python> = 3.2)
方法。使用它,我们可以将现有密钥移动到O(1)时间的字典的任一端。
Use OrderedDict.move_to_end()
(Python >= 3.2)
Python 3.2 introduced the OrderedDict.move_to_end()
method. Using it, we can move an existing key to either end of the dictionary in O(1) time.
>>> d1 = OrderedDict([('a', '1'), ('b', '2')])
>>> d1.update({'c':'3'})
>>> d1.move_to_end('c', last=False)
>>> d1
OrderedDict([('c', '3'), ('a', '1'), ('b', '2')])
如果我们需要插入一个元素并将其移动到顶部,全部在一个步骤中,我们可以直接使用它来创建一个 prepend()
包装(不在此处)
If we need to insert an element and move it to the top, all in one step, we can directly use it to create a prepend()
wrapper (not presented here).
如果您不想这样做,性能不是问题然后最简单的方法是创建一个新的dict:
If you don't want to do that and performance is not an issue then easiest way is to create a new dict:
from itertools import chain, ifilterfalse
from collections import OrderedDict
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in ifilterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
d1 = OrderedDict([('a', '1'), ('b', '2'),('c', 4)])
d2 = OrderedDict([('c', 3), ('e', 5)]) #dict containing items to be added at the front
new_dic = OrderedDict((k, d2.get(k, d1.get(k))) for k in \
unique_everseen(chain(d2, d1)))
print new_dic
输出:
OrderedDict([('c', 3), ('e', 5), ('a', '1'), ('b', '2')])
这篇关于如何在python中的OrderedDict顶部添加元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!