13

OrderedDictを使用してリストにランダムアクセスしていnextますが、リスト内のアイテムが必要です。

foo = OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
apple = foo['apple']

fooとだけを使ってバナナを手に入れるにはどうすればよいappleですか?

4

4 に答える 4

9

意図的に非公開にされているOrderedDict実装の部分にアクセスしても問題がない場合:

>>> class MyOrderedDict(OrderedDict):
...     def next_key(self, key):
...             next = self._OrderedDict__map[key][1]
...             if next is self._OrderedDict__root:
...                     raise ValueError("{!r} is the last key".format(key))
...             return next[2]
...     def first_key(self):
...             for key in self: return key
...             raise ValueError("OrderedDict() is empty")
... 
>>> od = MyOrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> od.next_key("apple")
'banana'
>>> od.next_key("banana")
'orange'
>>> od.next_key("orange")
'pear'
>>> od.next_key("pear")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in next_key
ValueError: 'pear' is the last key
>>> od.first_key()
'apple'
于 2012-09-08T09:26:57.677 に答える
6

I shudder to think how slow this will be on a list of size, but the only way I've come up with so far...

>>> foo.items()[foo.keys().index('apple') + 1]
('banana', 3)

Edit:

The example was slightly contrived; my actual collection is keyed by dates. If I need the entry after today; found a solution using dropwhile...

>>> foo = OrderedDict([(datetime.date(2000,1,1), 4), (datetime.date(2000,5,23), 3), datetime.date(2000,10,1), 2), (datetime.date(2000,12,31), 1)])
>>> today = datetime.date(2000,1,30)
>>> foo.items()[foo.keys().index((itertools.dropwhile(lambda d: d<today, foo)).next())]
(datetime.date(2000, 5, 23), 3)

Quite a mouthful.

于 2012-09-08T05:19:19.940 に答える
3

Python 3.X

dict.itemsは、リストではなく、反復可能なdictビューオブジェクトを返します。インデックス作成を可能にするために、呼び出しをリストにラップする必要があります。

>>> from collections import OrderedDict
>>> 
>>> foo = OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> 
>>> def next_item(odic, key):
...     return list(odic)[list(odic.keys()).index(key) + 1]
... 
>>> next = next_item(foo, 'apple')
>>> print(next, foo[next])
banana 3
于 2019-06-26T14:11:46.780 に答える
1

あなたのコードから作り直された、この方法は私が少し良くなると思います:

import collections as co
import datetime as dt
import itertools as it

foo = co.OrderedDict([
    (dt.date(2000,1,1), 4),
    (dt.date(2000,5,23), 3),
    (dt.date(2000,10,1), 2),
    (dt.date(2000,12,31), 1)
])
today = dt.date(2000,1,30)

fooiter = it.dropwhile(lambda d: d <= today, foo)
print next(fooiter)
print list(fooiter)

基本的に、適切な場所にイテレータを配置するだけで十分です。

任意の位置から反復を開始するのはクールですが、可能かどうかはわかりません。いくつかの考えが必要です。

于 2012-09-08T06:44:40.720 に答える