2012-09-08 18 views
8

मैं एक सूची रैंडम एक्सेस करने के लिए एक OrderedDict उपयोग कर रहा हूँ, लेकिन अब एक ही है कि मेरे पास है से सूची में next आइटम हैं:ऑर्डर्ड डिक्ट में "अगला" आइटम कैसे प्राप्त करें?

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

मैं केले सिर्फ foo और apple का उपयोग कर कैसे मिलता है?

+1

'OrderedDict' इस बात के लिए भी आसान हो रहा है। शायद एक भयानक एक लाइनर काम करेगा? 'foo [(lambda कुंजी: कुंजी [(keys.index (' नाशपाती ') + 1)% लेन (चाबियाँ)]) (foo.keys())] ' – Blender

उत्तर

7

आप 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' 
+1

ठीक से अधिक, यह वह अंतर्दृष्टि है जिसकी मैं उम्मीद कर रहा था। –

+0

पायथन 3.4 में 'ऑर्डर्ड डिक्ट' का कार्यान्वयन थोड़ा बदल गया (देखें [यहां] (https://hg.python.org/cpython/file/01437956ea67/Lib/collections/__init__.py#l85))। लिंक की गई सूची के तत्व अब एक डमी क्लास '_Link' की ऑब्जेक्ट्स हैं। 'Self._OrderedDict__map [key] [1]' तक पहुंचने के बजाय, किसी को 'self._OrderedDict__map [key] .next' तक पहुंच प्राप्त करनी चाहिए। –

+0

पायथन 3.5 चीजों में और भी बदले हुए प्रतीत होते हैं। ऑर्डर्डडिक्ट के कार्यान्वयन को पायथन से सी में ले जाया गया है। [Https://bugs.python.org/issue16991] देखें। यह कार्यान्वयन विरासत में होने के लिए _map i.e. _OrderedDict__map की अनुमति नहीं देगा। यदि आपको इसे रोकने और पाइथन मॉड्यूल का उपयोग करना है, तो 'py_coll = import_fresh_module ('संग्रह', अवरुद्ध = ['_ संग्रह']) ऑर्डर्डडिक्ट = py_coll.OrderedDict' – Mikki

5

मुझे लगता है कि यह कैसे धीमी गति से आकार की एक सूची पर होगा कंपकंपी, लेकिन केवल तरह से मैं अब तक लेकर आए हैं ...

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

संपादित करें:

उदाहरण थोड़ा सा था; मेरा वास्तविक संग्रह तारीखों के आधार पर है। अगर मुझे today के बाद प्रविष्टि की आवश्यकता है; बूंद का उपयोग करके एक समाधान मिला ...

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

काफी मुंह से।

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) 

सही जगह पर मूल रूप से होने इटरेटर पहले से ही पर्याप्त है।

किसी भी स्थिति से पुनरावृत्ति शुरू करने के लिए अच्छा होगा, लेकिन यह सुनिश्चित नहीं है कि यह कितना संभव है। कुछ विचार की जरूरत है।

संबंधित मुद्दे