पाइथन 3 में सूचकांक द्वारा डिक्टिंग_की तत्व तक पहुँचना


131

मैं एक श्रुत_ तत्व को उसके सूचकांक द्वारा एक्सेस करने की कोशिश कर रहा हूँ:

test = {'foo': 'bar', 'hello': 'world'}
keys = test.keys()  # dict_keys object

keys.index(0)
AttributeError: 'dict_keys' object has no attribute 'index'

मैं पाना चाहता हूं foo

के जैसा:

keys[0]
TypeError: 'dict_keys' object does not support indexing

मैं यह कैसे कर सकता हूँ?


9
Py3.x में dict.keys()दृश्य ऑब्जेक्ट की तरह एक सेट लौटाता है, सूची नहीं (इसलिए, अनुक्रमण संभव नहीं है)। उपयोगkeys = list(test)
अश्विनी चौधरी

जब मैं सूची (कुछ-कुछ) करता हूं, तो टपल ऑर्डर यादृच्छिक होता है: उदाहरण: सूची ({'foo': 'bar', 'hello': 'world'}) वापस आ सकता है: सूची (foo, hello) या सूची (hello,) फू), यह यादृच्छिक क्यों है?
fj123x

7
डिकट्स के पास कोई आदेश नहीं है । ( collections.OrderedDictयदि आप कुंजियों का आदेश चाहते हैं तो उपयोग करें )
अश्विनी चौधरी

इस समस्या को हल करने के लिए विभिन्न दृष्टिकोणों को पुनः स्वीकार करते
पॉल

जवाबों:


161

list()इसके बजाय शब्दकोश पर कॉल करें :

keys = list(test)

पायथन 3 में, dict.keys()विधि एक डिक्शनरी व्यू ऑब्जेक्ट लौटाती है , जो एक सेट के रूप में कार्य करती है। सीधे शब्दकोष में परिवर्तन करने से भी कुंजी निकलती है, इसलिए किसी शब्दकोश को सूची में बदलने से सभी कुंजियों की सूची बन जाती है:

>>> test = {'foo': 'bar', 'hello': 'world'}
>>> list(test)
['foo', 'hello']
>>> list(test)[0]
'foo'

3
पायथन 3 में सूची (तानाशाही ()) के लिए देखें - लैबिक्स ब्लॉग स्पष्ट रूप से बताता है कि समस्या समाधान प्रदान किए बिना क्या है। यह उत्कृष्ट है!
ब्रैंडन ब्रैडली

@BrandonBradley: आम तौर पर बोलना: परमाणु होने पर कुछ कार्यों पर भरोसा करना वैसे भी एक बुरा विचार है, क्योंकि पायथन इतना गतिशील है। आपके कोड को आसानी से एक dictउपवर्ग पास किया जा सकता है , उदाहरण के लिए, जहां .keys()पायथन कोड संभाला जाता है (उदाहरण के लिए एक थ्रेड स्विच हो सकता है)।
मार्टिन पीटर्स

@BrandonBradley: लिंक के लिए धन्यवाद। केवल उस ब्लॉग के लिए टिप्पणियों में से एक से समाधान पायथन 3 में मेरे लिए काम करता है: सॉर्ट किया गया (तानाशाही। ())। Python2 में, dict.keys () प्रमुख मूल्यों की सूची लौटाएगा।
गुड विल

2
@ गुडविल: sorted(dict)ठीक यही काम करेगा; क्रमबद्ध क्रम में कुंजियों की एक सूची तैयार करें। list(dict)आपको शब्दकोश क्रम में सूची देगा।
मार्टिन पीटर्स

1
या उपयोग कर सकते हैंkeys = [*test]
Alex78191

59

एक पूर्ण उत्तर नहीं है लेकिन शायद एक उपयोगी संकेत है। यदि यह वास्तव में पहला आइटम है जो आप चाहते हैं *, तो

next(iter(q))

की तुलना में बहुत तेज है

list(q)[0]

बड़े dicts के लिए, चूंकि पूरी चीज़ को मेमोरी में स्टोर करने की आवश्यकता नहीं है।

10.000.000 आइटम के लिए मैंने इसे लगभग 40.000 गुना तेज पाया।

* पाइथन 3.6 से पहले एक छद्म-यादृच्छिक वस्तु होने के मामले में पहला आइटम (इसके बाद इसे मानक कार्यान्वयन में आदेश दिया गया है, हालांकि इस पर भरोसा करने की सलाह नहीं दी गई है)।


5
यह हमेशा मेरे सबसे बड़े मुद्दों में से एक रहा है, जो कि Py3 में पुनरावृत्तियाँ बन रहा है। यह निश्चित रूप से अधिक कुशल है, लेकिन इतने सारे उपयोग मामले "अशुद्ध" हो जाते हैं और बिना किसी कारण के जटिल हो जाते हैं। उदाहरण के लिए, वे केवल प्रदर्शन हानि होने के बिना, इट्रेटर पर अनुक्रमण का समर्थन क्यों नहीं कर सकते?
एहसान किआ

2

मैं पहले शब्दकोश आइटम की "कुंजी" और "मूल्य" जोड़ी चाहता था। मैंने निम्नलिखित कोड का उपयोग किया।

 key, val = next(iter(my_dict.items()))

0
test = {'foo': 'bar', 'hello': 'world'}
ls = []
for key in test.keys():
    ls.append(key)
print(ls[0])

परंपरागत रूप से परिभाषित सूची में कुंजियों को जोड़ने और फिर उसी के लिए अनुक्रमण करने का पारंपरिक तरीका


2
यह गलत नहीं है, लेकिन क्यों नहीं ls = list(test.keys())? मुझे यह अधिक सरल लगता है।
वैलेंटिनो

हां, यह अधिक कुशल है। मैंने यह सिर्फ पठनीयता दिखाने के लिए लिखा था।
प्रणव दुआ

0

कई मामलों में, यह एक XY समस्या हो सकती है । आप अपनी शब्दकोश कुंजियों को स्थिति के अनुसार क्यों अनुक्रमित कर रहे हैं क्या आपको वास्तव में जरूरत है? हाल तक तक, पायथन में शब्दकोशों का भी आदेश नहीं दिया गया था, इसलिए पहले तत्व तक पहुंचना मनमाना था।

मैंने अभी कुछ पायथन 2 कोड का अनुवाद पायथन 3 में किया है:

keys = d.keys()
for (i, res) in enumerate(some_list):
    k = keys[i]
    # ...

जो सुंदर नहीं है, लेकिन बहुत बुरा भी नहीं है। पहले, मैं इसे राक्षसी द्वारा प्रतिस्थापित करने वाला था

    k = next(itertools.islice(iter(keys), i, None))

इससे पहले कि मुझे एहसास हुआ कि यह सब बहुत बेहतर लिखा गया है

for (k, res) in zip(d.keys(), some_list):

जो ठीक काम करता है।

मेरा मानना ​​है कि कई अन्य मामलों में, स्थिति के आधार पर शब्दकोश कुंजी को अनुक्रमित करने से बचा जा सकता है। हालाँकि, Python 3.7 में शब्दकोशों का आदेश दिया गया है, उस पर निर्भर होना सुंदर नहीं है। उपरोक्त कोड केवल इसलिए काम करता है क्योंकि की सामग्री some_listहाल ही में सामग्री से उत्पादित की गई थी d

यदि आपको वास्तव में disk_keysअनुक्रमणिका द्वारा किसी तत्व तक पहुंचने की आवश्यकता है, तो अपने कोड को देखें । शायद आप की जरूरत नहीं है


0

इसे इस्तेमाल करे

keys = [next(iter(x.keys())) for x in test]
print(list(keys))

परिणाम इस तरह दिखता है। ['फू', 'हैलो']

आप अधिक संभावित समाधान यहां पा सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.