2013-07-02 5 views
51

का उपयोग कर यह मेरा कोड है:प्राप्त करें: लेखन त्रुटि: 'dict_values' वस्तु अनुक्रमण का समर्थन नहीं करता जब अजगर 3.2.3

{names[i]:d.values()[i] for i in range(len(names))} 

यह पूरी तरह से ठीक काम करता है जब अजगर 2.7.3 का उपयोग; हालांकि, जब मैं पायथन 3.2.3 का उपयोग करता हूं, तो मुझे 'dict_values' object does not support indexing बताते हुए एक त्रुटि मिलती है। 3.2.3 के लिए इसे संगत बनाने के लिए मैं कोड को कैसे संशोधित कर सकता हूं?

+1

'मूल्य' अब एक दृश्य वस्तु देता है http://docs.python.org/3.2/library/stdtypes.html#dictionary-view-objects – dm03514

+3

आप एक 'मूल्य' से वापस आने वाले 'मूल्य' के आदेश पर भरोसा क्यों कर रहे हैं वैसे भी शब्दकोश? –

+0

हाँ, यह कोड अविश्वसनीय है जब तक कि डी 'ऑर्डर्ड डिक्ट' नहीं है - और ऐसा लगता है कि ऐसा लगता है कि वहां एक बेहतर तरीका होना चाहिए। –

उत्तर

81

पायथन 3, dict.values() (dict.keys() और dict.items() के साथ) एक सूची के बजाय view देता है। प्रलेखन here देखें। इसलिए आपके कॉल तो जैसे list के लिए एक कॉल में dict.values() को रैप करने के लिए की जरूरत है:

v = list(d.values()) 
{names[i]:v[i] for i in range(len(names))} 
+1

@ जेसेपेट ऐसा लगता है कि आपने गलत तरीके से 'मूल्य' के रूप में गलत तरीके से 'वाउल्स' के रूप में लिखा होगा। – andersschuller

+0

@andersshuller: आप सही थे। –

+1

ओपी का कोड इस पर ध्यान देने वाले सभी के लिए अवांछित है - पायथन में हम इंडेक्स से बचते हैं (धीमे, उलझन में)। सही तरीका @ डेविडरोबिन्सन के [उत्तर] के अनुसार है (https://stackoverflow.com/a/17431678/281545): 'dict (ज़िप (नाम, d.values ​​()))'। निस्संदेह यह कोड उन नामों के रूप में क्रमबद्ध मानों पर भी निर्भर करता है जो किसी भी तरह से गारंटीकृत नहीं हैं। –

6

अपने कोड का एक सरल संस्करण होगा:

vlst = list(d.values()) 
{names[i]: vlst[i] for i in range(len(names))} 

(तुम बस के रूप में आसानी list(d.values()) रख सकते हैं:

dict(zip(names, d.values())) 

आप एक ही संरचना को बनाए रखना चाहते हैं, तो आप इसे करने के लिए बदल सकते हैं vlst की बजाय समझ के अंदर; ऐसा करने के लिए बस इतना अपमानजनक है क्योंकि यह हर बार सूची को पुन: उत्पन्न करेगा)।

+0

असुविधाजनक रूप से, जब मैं vlst उदाहरण का उपयोग करता हूं, तो मुझे एक त्रुटि मिलती है "'dict' ऑब्जेक्ट में कोई विशेषता नहीं है 'मान' –

+0

@ जेसेपेट: मुझे नहीं लगता कि यह कैसे संभव है, खासकर जब से आपके अपने कोड 'd.values ​​() में बिना किसी त्रुटि के काम किया (जब तक आप इसे अनुक्रमित करने की कोशिश नहीं करते)।क्या यह संभव है कि आपने 'मान' या कुछ समान त्रुटि गलत वर्तनी की है? –

+0

मैंने मूल्यों को गलत तरीके से गलत नहीं किया है, यह मुझे आश्चर्यजनक है कि कम से कम –

2

अजगर 3 में dict.values() विधि देता है एक dictionary view object, नहीं एक सूची है जैसे कि यह अजगर में करता है 2. शब्दकोश विचारों लंबाई है, पुनरावृत्त किया जा सकता है, और सदस्यता परीक्षण का समर्थन कर सकते हैं, लेकिन अनुक्रमण का समर्थन नहीं करते हैं।

दोनों संस्करणों में अपने कोड काम करने के लिए, आप इस्तेमाल कर सकते हैं या तो या तो इन:

{names[i]:value for i,value in enumerate(d.values())} 

        या

values = list(d.values()) 
{name:values[i] for i,name in enumerate(names)} 

अब तक का सबसे सरल, सबसे तेज़ तरीका किसी भी संस्करण में एक ही चीज़ करने के लिए:

dict(zip(names, d.values())) 

नोट हालांकि, ये सभी विधियां आपको परिणाम देगी जो d की वास्तविक सामग्री के आधार पर अलग-अलग होंगी। उस पर काबू पाने के लिए, आप इसके बजाय OrderedDict का उपयोग कर सकते हैं, जो उस क्रम को याद रखता है जिसमें कुंजी को पहले डाला गया था, ताकि आप values() विधि द्वारा लौटाए गए क्रम के क्रम पर भरोसा कर सकें।

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