TypeError: 'dict_keys' ऑब्जेक्ट इंडेक्सिंग का समर्थन नहीं करता है


144
def shuffle(self, x, random=None, int=int):
    """x, random=random.random -> shuffle list x in place; return None.

    Optional arg random is a 0-argument function returning a random
    float in [0.0, 1.0); by default, the standard random.random.
    """

    randbelow = self._randbelow
    for i in reversed(range(1, len(x))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = randbelow(i+1) if random is None else int(random() * (i+1))
        x[i], x[j] = x[j], x[i]

जब मैं shuffleफ़ंक्शन चलाता हूं तो यह निम्न त्रुटि उठाता है, ऐसा क्यों है?

TypeError: 'dict_keys' object does not support indexing

7
एक python3 त्रुटि लगती है
DataEngineer

जवाबों:


231

स्पष्ट रूप से आप d.keys()अपने shuffleकार्य में गुजर रहे हैं । संभवतः यह python2.x (जब d.keys()किसी सूची को लौटाया गया) के साथ लिखा गया था । Python3.x के साथ, d.keys()एक ऐसी dict_keysवस्तु लौटाता है , जो a की setतुलना में बहुत अधिक व्यवहार करती है list। जैसे, यह अनुक्रमित नहीं किया जा सकता है।

समाधान list(d.keys())(या बस list(d)) पास करना है shuffle


22
। । । या बस list(d)जो आपको python2.x और python3.x पर चाबियों की एक सूची देगा, बिना किसी कॉपी के :-):
mgilson

11
यह पायथन 3 के लिए एक अजीब ब्रेकिंग चेंज डिज़ाइन निर्णय है।
जेसन

9
आप ऐसा सोच सकते हैं, लेकिन मुझे निश्चित रूप से लगता है कि यह सही निर्णय था। dict_keysवस्तु एक बहुत अधिक एक dict की बस कुंजियां आधा तरह बर्ताव करता है। विशेष रूप से, वे ओ (1) सदस्यता परीक्षण (और अन्य सेट-जैसे तरीकों को उस तथ्य के शीर्ष पर कुशलता से लागू किया जा सकता है) का समर्थन करते हैं। ये चीजें किसी सूची के साथ संभव नहीं हैं और यदि आप तानाशाह की चाबियों की सूची चाहते हैं, तो आप इसे list(your_dictionary)प्राप्त करने के लिए हमेशा सक्षम हैं ।
mgilson

मेरे लिए यह देखना उपयोगी है कि python3 को हमें सूची के साथ शब्दकोश को लपेटने की आवश्यकता है।
DataEngineer

2
@Crt - shuffleमूल पोस्टर कोड में फ़ंक्शन का नाम है (फ़ंक्शन जो त्रुटि फेंक रहा है)। कोड को देखते हुए, मुझे लगता है कि यह random.shuffleमानक पुस्तकालय में कॉपी के कार्यान्वयन से कॉपी / पेस्ट किया गया था :-)
mgilson

11

आप somedict.keys()फ़ंक्शन का परिणाम पास कर रहे हैं । पायथन 3 में, dict.keysकोई सूची नहीं लौटाता है, लेकिन एक सेट-जैसी वस्तु जो शब्दकोश की कुंजियों के दृश्य का प्रतिनिधित्व करती है और (सेट-जैसे होने) अनुक्रमण का समर्थन नहीं करती है।

समस्या को ठीक list(somedict.keys())करने के लिए, कुंजी एकत्र करने के लिए उपयोग करें, और उसी के साथ काम करें।


10

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

next(iter(keys))

या, यदि आप सभी वस्तुओं पर पुनरावृति करना चाहते हैं, तो आप उपयोग कर सकते हैं:

items = iter(keys)
while True:
    try:
        item = next(items)
    except StopIteration as e:
        pass # finish

1

जब आपको पहले से मौजूद है तो आपको फेरबदल लागू करने की आवश्यकता क्यों है? दिग्गजों के कंधों पर रहें।

import random

d1 = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',
     5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'}

keys = list(d1)
random.shuffle(keys)

d2 = {}
for key in keys: d2[key] = d1[key]

print(d1)
print(d2)

उत्तर सामान्य-ज्ञान प्रासंगिक है, लेकिन यह ओपी से जो पूछ रहा था, उसे संबोधित नहीं करता है।
जेसी रोकोमांडे

आप सही हे। ऐसा लगता है कि वह अपने रैंडमाइज़र को लागू करना चाहते हैं।
FooBar167

1
psah, शायद वह वास्तव में नहीं जानता था कि वह बिल्ट-इन का उपयोग कर सकता है, लेकिन प्रश्न वास्तव में एक प्रकार की त्रुटि के बारे में लगता है। फिर भी, मुझे आशा है कि उन्होंने मूल DRY और कोड-इकोनॉमी सिद्धांतों का पालन करने के लिए आपके विकल्प को स्विच किया और उपयोग किया (जब तक कि यह बहुत विशिष्ट नहीं है)।
जेसी रोक्मोंडे

1

पायथन 2 में श्रुतलेख। () एक सूची लौटाता है, जबकि पायथन 3 में यह एक जनरेटर लौटाता है।

आप इसे केवल उन मूल्यों पर पुनरावृत्त कर सकते हैं जिन्हें आपको स्पष्ट रूप से सूची में परिवर्तित करना पड़ सकता है अर्थात इसे किसी सूची फ़ंक्शन में पास कर सकते हैं।

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