本文介绍了如何在python中的OrderedDict顶部添加元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个

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 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顶部添加元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-05 11:13