当前位置: 首页 > 面试题库 >

如何在OrderedDict的开头添加元素?

郭远
2023-03-14
问题内容

我有这个:

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中没有执行此操作的内置方法。如果需要此操作,则需要编写一种以O(1)复杂度prepend()OrderedDict内部操作的方法/函数。

对于Python 3.2和更高版本,
使用move_to_end方法。该方法接受一个last参数,该参数指示元素将被移动到的底部(last=True)还是顶部(last=FalseOrderedDict

最后,如果您想要一种快速,肮脏且 缓慢的 解决方案,则可以OrderedDict从头开始创建一个新的解决方案

四种不同解决方案的详细信息:

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对象的独立功能

该函数通过接受dict对象,键和值来做同样的事情。我个人更喜欢上课:

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)

演示:

>>> 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)

Python
3.2引入
了该OrderedDict.move_to_end()方法。使用它,我们可以在O(1)时间将现有键移动到字典的任一端。

>>> 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()包装器(此处未显示)。

创建一个新的OrderedDict-慢!!!

如果您不想这样做并且 性能不是问题, 那么最简单的方法是创建一个新的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')])


 类似资料:
  • 问题内容: 我需要将元素添加到队列中,但是当我调用函数添加元素时,我希望它在数组的开头添加元素(因此它具有最低的索引),并且如果数组有10个元素添加一个新的结果将删除最旧的元素(具有最高索引的元素)。 有没有人有什么建议? 问题答案: 具有方法,因此您可以使用: 之后,您可以使用以下命令删除最后一个元素: 但是,您可能需要重新考虑您的要求或使用其他数据结构,例如 编辑 也许看看Apache的: 是

  • 问题内容: 我需要在数组的开头添加或添加元素。 例如,如果我的数组如下所示: 我的AJAX调用的响应是,我希望更新后的数组如下所示: 目前,我正打算这样做: 有什么更好的方法吗?Javascript是否具有执行此操作的任何内置功能? 我的方法很复杂,看到更好的实现将真的很有趣。 问题答案: 使用。就像一样,除了它在数组的开头而不是结尾添加元素。 // -将元素添加到数组的开头/结尾 // -删除并

  • 问题内容: 我正在尝试通过 “深度” 键对OrderedDict中的OrderedDict进行排序。有什么解决方案可以对Dictionary进行排序吗? 排序的字典应如下所示: 知道如何获得它吗? 问题答案: 由于按插入顺序排序,因此您必须创建一个新的。 在您的情况下,代码如下所示: 有关更多示例,请参见http://docs.python.org/dev/library/collections.

  • 我需要在队列中添加元素,但当我调用函数添加元素时,我希望它在数组的开头添加元素(因此它的索引最低),如果数组有10个元素,添加一个新元素将导致删除最旧的元素(索引最高的元素)。 有人有什么建议吗?

  • 问题内容: 我有以下bash代码,该代码逐行循环通过文本文件.. im试图为每行添加工作前缀’prefix’,但是却出现此错误: 这是bash脚本.. 我在这里做错了什么? 更新:从头开始将所有行都转储到终端的一行中,可能相关吗? 问题答案: 单行awk命令也可以做到这一点:

  • 问题内容: 我有一个来自oracle的NO.net Web服务,要访问,我需要添加soap标头。如何在Java中添加soap标头? 这有必要吗? 我的肥皂标头是这样的: 问题答案: 我做到了,只需按照本教程进行即可。很有帮助 是来自javadb的副本(因为已关闭) http://informatictips.blogspot.pt/2013/09/using-message-handler-to-