প্রকারের ত্রুটি: 'ডিকট_কিজ' অবজেক্ট ইনডেক্সিং সমর্থন করে না


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
পাইথন 3 ত্রুটি বলে মনে হচ্ছে
ডেটাজিনিয়ার

উত্তর:


231

স্পষ্টতই আপনি d.keys()আপনার shuffleফাংশনে প্রবেশ করছেন। সম্ভবত এটি পাইথন 2.x দিয়ে লেখা হয়েছিল (যখন d.keys()কোনও তালিকা ফিরে আসে)। পাইথন 3.x এর সাহায্যে এমন d.keys()একটি dict_keysবস্তু প্রদান করে যা একটি এর setচেয়ে অনেক বেশি আচরণ করে list। যেমন, এটি সূচী করা যায় না।

সমাধানটি list(d.keys())(বা সহজভাবে list(d)) পাস করা shuffle


22
। । । বা ঠিক list(d)কোনটি আপনাকে কোনও অনুলিপি না করে পাইথন ২.x এবং পাইথন ৩.x উভয় কীগুলির একটি তালিকা দেবে :-)
ম্যাগসিলসন

11
পাইথন 3 এর জন্য এটি একটি অদ্ভুত ব্রেকিং চেঞ্জ ডিজাইনের সিদ্ধান্ত।
জেসন

9
আপনি সম্ভবত এটি ভাবতে পারেন, তবে আমি অবশ্যই মনে করি এটি সঠিক সিদ্ধান্ত ছিল। dict_keysবস্তুর আরো অনেক একটি অভি মাত্র চাবি অর্ধেক মত আচরণ করে। বিশেষত, তারা ও (1) সদস্যতা পরীক্ষার (এবং অন্যান্য সেট-মত পদ্ধতিগুলি সমর্থন করে যা সত্যের উপরে দক্ষতার সাথে প্রয়োগ করা যেতে পারে)। এই জিনিসগুলি কোনও তালিকার দ্বারা সম্ভব নয় এবং যদি আপনি ডিকের কীগুলির একটি তালিকা চান তবে আপনি list(your_dictionary)এটি পেতে সর্বদা সহজভাবে সক্ষম হয়েছি ।
মিগিলসন

পাইথন 3 এর জন্য আমাদের অভিধানটি অভিধানের সাথে মোড়ক করা প্রয়োজন এটি দেখার জন্য এটি আমার পক্ষে সহায়ক।
ডেটাজিনিয়ার

2
@ সিআরটি - shuffleহ'ল মূল পোস্টারের কোডে (ফাংশন যা ত্রুটি ছুঁড়েছে) এর নাম। কোডটি দেখে, আমি মনে করি যে এটি random.shuffleস্ট্যান্ডার্ড লাইব্রেরিতে প্রয়োগকরণ থেকে অনুলিপি / আটকানো হয়েছিল :-)
মিগিলসন

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
হ্যাঁ, তিনি সম্ভবত তিনি অন্তর্নির্মিতটি ব্যবহার করতে পারবেন তা জানেন না, তবে প্রশ্নটি আসলে টাইপ-ত্রুটি সম্পর্কিত বলে মনে হচ্ছে। তবুও, আমি আশা করি যে তিনি বেসিক ডিআরওয়াই এবং কোড-ইকোনমি নীতির অনুসরণ করতে আপনার বিকল্পটি (যদি এটি খুব নির্দিষ্ট কিছু না বলে) স্যুইচ করে এবং ব্যবহার করেছেন used
জেসি রোকামন্ডে

1

পাইথন 2 2 ডট.কেজ () একটি তালিকা ফিরিয়ে দেয়, যেখানে পাইথন 3 এ এটি একটি জেনারেটর দেয়।

আপনি কেবলমাত্র এর মানগুলি নিয়েই পুনরাবৃত্তি করতে পারেন অন্যথায় আপনাকে এটি স্পষ্টভাবে কোনও তালিকায় রূপান্তর করতে হতে পারে অর্থাৎ এটি কোনও তালিকা ফাংশনে স্থান দিতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.