python如何往dict里添加元素_如何在python中的OrderedDict的顶部添加一个元素?

在Python 2中没有内置的方法。如果你需要这个,你需要编写一个prepend()方法/函数,对O(1)复杂度的OrderedDict内部操作。

对于Python 3.2和更高版本,可以使用move_to_end1方法。该方法接受最后一个参数,该参数指示元素是否将移动到OrderedDict的底部(last = True)或顶部(last = False)。

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

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

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

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

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值