访问由指数的collections.OrderedDict项目访问由指数的collections.O

2019-05-13 11:24发布

可以说,我有以下代码:

import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'

有没有一种方法,我可以访问项目的编号方式,比如:

d(0) #foo's Output
d(1) #bar's Output

Answer 1:

如果它的OrderedDict()你可以很容易地通过获取的(键,值)对元组按如下方式访问通过索引的元素

>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>> d.items()[0]
('foo', 'python')
>>> d.items()[1]
('bar', 'spam')

注意:为Python 3.X

dict.items将返回一个可迭代的字典视图对象 ,而不是一个列表。 我们需要调用换到一个列表,以便使索引可能

>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')


Answer 2:

你必须使用一个OrderedDict或者你特别希望的是在某些方面具有快速定位索引下令地图样类型? 如果是后者,则考虑Python的许多分类字典类型之一(哪些订单基于关键字排序顺序键 - 值对)。 某些实现还支持快速索引。 例如, sortedcontainers项目具有SortedDict只是为此类型。

>>> from sortedcontainers import SortedDict
>>> sd = SortedDict()
>>> sd['foo'] = 'python'
>>> sd['bar'] = 'spam'
>>> print sd.iloc[0] # Note that 'bar' comes before 'foo' in sort order.
'bar'
>>> # If you want the value, then simple do a key lookup:
>>> print sd[sd.iloc[1]]
'python'


Answer 3:

这里是一个特殊的情况下,如果你想在第一项(或接近)在OrderedDict,而无需创建一个列表:

>>> from collections import OrderedDict
>>> 
>>> d = OrderedDict()
>>> d["foo"] = "one"
>>> d["bar"] = "two"
>>> d["baz"] = "three"
>>> 
>>> d.iteritems().next()
('foo', 'one')

(你第一次说“下一个()”,它真正的意思是“第一”。)

在我在Python 2.7的非正式测试中, iteritems().next()一个小OrderedDict只比一点点更快的items()[0] 用10,000个条目,的OrderedDict iteritems().next()是快约200倍items()[0]

但是 ,如果你保存的物品()列表一次,然后使用列表很多,这可能会更快。 或者,如果你反复{创建iteritems()迭代器,并通过它一步到你想要的位置},可能会比较慢。



Answer 4:

这是显着更有效地从使用IndexedOrderedDict indexed包。

继尼古拉斯的评论,我已经做OrderedDictIndexedOrderedDict基准与1000个条目。

In [1]: from numpy import *
In [2]: from indexed import IndexedOrderedDict
In [3]: id=IndexedOrderedDict(zip(arange(1000),random.random(1000)))
In [4]: timeit id.keys()[56]
1000000 loops, best of 3: 969 ns per loop

In [8]: from collections import OrderedDict
In [9]: od=OrderedDict(zip(arange(1000),random.random(1000)))
In [10]: timeit od.keys()[56]
10000 loops, best of 3: 104 µs per loop

IndexedOrderedDict是〜在在这种具体情况下具体的位置标定元件快100倍。



Answer 5:

这个社区维基试图收集现有的答案。

Python 2.7版

在Python 2中, keys() values()items()的函数OrderedDict返回列表。 使用values为例,最简单的方法是

d.values()[0]  # "python"
d.values()[1]  # "spam"

对于大集合,你只关心一个单一的指标,你能避免使用发电机版本,创建完整列表iterkeysitervaluesiteritems

import itertools
next(itertools.islice(d.itervalues(), 0, 1))  # "python"
next(itertools.islice(d.itervalues(), 1, 2))  # "spam"

该indexed.py包提供IndexedOrderedDict ,这是专为这种使用情况下,将是最快的选项。

from indexed import IndexedOrderedDict
d = IndexedOrderedDict({'foo':'python','bar':'spam'})
d.values()[0]  # "python"
d.values()[1]  # "spam"

使用itervalues可以用随机存取大型辞书相当快:

$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000;   d = OrderedDict({i:i for i in range(size)})'  'i = randint(0, size-1); d.values()[i:i+1]'
1000 loops, best of 3: 259 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000;  d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
100 loops, best of 3: 2.3 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
10 loops, best of 3: 24.5 msec per loop

$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000;   d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
10000 loops, best of 3: 118 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000;  d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
1000 loops, best of 3: 1.26 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
100 loops, best of 3: 10.9 msec per loop

$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 1000;   d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.19 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 10000;  d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.24 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 100000; d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.61 usec per loop

+--------+-----------+----------------+---------+
|  size  | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
|   1000 | .259      | .118           | .00219  |
|  10000 | 2.3       | 1.26           | .00224  |
| 100000 | 24.5      | 10.9           | .00261  |
+--------+-----------+----------------+---------+

Python的3.6

Python 3中有相同的两个基本选项(名单VS发电机),但字典方法默认返回发电机。

列表方法:

list(d.values())[0]  # "python"
list(d.values())[1]  # "spam"

发生器方法:

import itertools
next(itertools.islice(d.values(), 0, 1))  # "python"
next(itertools.islice(d.values(), 1, 2))  # "spam"

Python 3本的词典是一个数量级比蟒2更快,具有用于使用生成类似的加速比。

+--------+-----------+----------------+---------+
|  size  | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
|   1000 | .0316     | .0165          | .00262  |
|  10000 | .288      | .166           | .00294  |
| 100000 | 3.53      | 1.48           | .00332  |
+--------+-----------+----------------+---------+


Answer 6:

这是一个新时代,与Python 3.6.1字典现在保留其顺序。 这些语义不明确的,因为这将需要BDFL批准。 但雷蒙德赫廷杰是未来最好的事情(和滑稽),他使一个相当强的情况下,该词典将被责令一段很长的时间。

因此,现在可以很容易地创建一个字典的切片:

test_dict = {
                'first':  1,
                'second': 2,
                'third':  3,
                'fourth': 4
            }

list(test_dict.items())[:2]

注:现在Dictonary插入顺序保存是官方在Python 3.7 。



Answer 7:

对于OrderedDict(),则可以通过获得的(键,值)对元组,如下所示,或者使用通过索引访问元素的.values()'

>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>>d.values()
odict_values(['python','spam'])
>>>list(d.values())
['python','spam']


文章来源: Accessing items in an collections.OrderedDict by index