ডিক.কেট (কী) কাজ করে তবে ডিক [কী] কাজ করে না কেন?


17

আমি স্ট্রিংয়ের মধ্যে কতজন রয়েছে তার উপর ভিত্তি করে নির্দিষ্ট সংখ্যার বাইনারি স্ট্রিংগুলি একসাথে গ্রুপ করার চেষ্টা করছি।

এটি কাজ করে না:

s = "0 1 3 7 8 9 11 15"
numbers = map(int, s.split())
binaries = [bin(x)[2:].rjust(4, '0') for x in numbers]

one_groups = dict.fromkeys(range(5), [])
for x in binaries:
    one_groups[x.count('1')] += [x]

প্রত্যাশিত অভিধান হওয়া one_groupsদরকার

{0: ['0000'], 
 1: ['0001', '1000'], 
 2: ['0011', '1001'], 
 3: ['0111', '1011'], 
 4: ['1111']}

তবে আমি পেয়েছি

{0: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 1: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 2: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 3: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 4: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111']}

এখন পর্যন্ত কেবলমাত্র কাজটিই হ'ল আমি যদি এর one_groups[x.count('1')] = one_groups.get(x.count('1')) + [x]পরিবর্তে ব্যবহার করিone_groups[x.count('1')] += [x]

তবে কেন এমন হয়? আমি যদি সঠিকভাবে স্মরণ করি, তবে dict[key]কীভাবে dict.get(key)কাজ করে তার অনুরূপ সেই অভিধানটির মান ফেরত দেওয়ার কথা নয় ? আমি এই থ্রেডটি দেখেছি কেন ডিকের পরিবর্তে ডিক.কেট (কী)? তবে এটি এই বিশেষ মামলার জন্য আমার প্রশ্নের উত্তর দেয় নি, যেহেতু আমি নিশ্চিতভাবেই জানি যে প্রোগ্রামটি পাওয়ার কথা নয়KeyError

আমি চেষ্টা করেছি one_groups[x.count('1')].append(x)কিন্তু এটিও কাজ করে না।


8
getNoneকী উপস্থিত না থাকলে বা কোনও সরবরাহিত ডিফল্ট মান উপস্থিত না করে ফেরত পাঠান, অন্যদিকে []কী না থাকলে সূচক অপারেটর একটি ত্রুটি বাড়ায়।
আদনানমুতলেব

সিডেনোট, bin(x)[2:].rjust(4, '0')এটিকে সরলীকৃত করা যেতে পারে '{:0>4b}'.format(x)
wjandrea

1
বিটিডাব্লু এটি একটি ন্যূনতম প্রজননযোগ্য উদাহরণ তৈরি করতে সহায়তা করে । এই ক্ষেত্রে আপনি কীভাবে binariesপ্রশ্নটি প্রাসঙ্গিক নয় তাই আপনি কেবল এর মান সরবরাহ করতে পারেন।
wjandrea

উত্তর:


24

সমস্যাটি হ'ল পরিবর্তনের বিষয়টি:

one_groups = dict.fromkeys(range(5), [])- এটি সমস্ত কীতে মান হিসাবে একই তালিকাটি পাস করে । সুতরাং আপনি যদি একটি মান পরিবর্তন করেন তবে আপনি সেগুলি সব পরিবর্তন করেন।

এটি মূলত বলার মতোই:

tmp = []
one_groups = dict.fromkeys(range(5), tmp)
del tmp

আপনি যদি একটি নতুন তালিকা ব্যবহার করতে চান তবে আপনাকে এটি একটি লুপে করতে হবে - হয় সুস্পষ্ট forলুপ বা ডিক বোঝার জন্য:

one_groups = {key: [] for key in range(5)}

এই জিনিসটি প্রতিটি []কীগুলির জন্য "চালিত" (যা সমান list()) হয়, এইভাবে বিভিন্ন তালিকার সাহায্যে মান তৈরি করে।


getকাজ করে কেন ? কারণ আপনি স্পষ্টভাবে বর্তমান তালিকাটি নিচ্ছেন তবে +একটি নতুন ফলাফলের তালিকা তৈরি করেছেন। আর এটা কোন ব্যাপার না কিনা এটা one_groups[x.count('1')] = one_groups.get(x.count('1')) + [x]বা one_groups[x.count('1')] = one_groups[x.count('1')] + [x]- আসলে একটি আছে যে +

আমি জানি যে সবাই কীভাবে a+=bন্যায়সঙ্গত বলে a=a+b, তবে প্রয়োগটি অপ্টিমাইজেশনের জন্য আলাদা হতে পারে - তালিকাগুলির ক্ষেত্রে +=এটি কেবল .extendকারণ আমরা জানি যে আমরা বর্তমানের পরিবর্তনশীলতে আমাদের ফলাফলটি চাই, সুতরাং নতুন তালিকা তৈরি করা স্মৃতির অপচয় হবে।


আহ, হ্যাঁ, বুঝেছি। আমার মনে আছে যখন আমি একটি 2 ডি তালিকা তৈরি করতে চেয়েছিলাম mylist = [[] * 5] * 5এবং কীভাবে mylist = [[] for x in range(5)] * 5এটি স্থির করেছিলাম একই ধরণের সমস্যা হচ্ছে । কেবল তাত্পর্যপূর্ণ স্পষ্টতার জন্য, আমি বুঝতে পেরেছি, ভেরিয়েবলগুলি খালি তালিকার মেমরির ঠিকানার দিকে ইঙ্গিত করার কারণে এটি ঘটে। এর পরিবর্তে যদি আমি এর পরিবর্তে আদিম ব্যবহার করি তবে সমস্যাটি কি ঘটে না?
স্পেকট্রাএক্সসিডিডি

1
হ্যাঁ, আপনি যদি আদিম ব্যবহার করেন এটি এটি সমাধান করবে তবে ভেঙে যাবে one_groups[x.count('1')] += [x]কারণ আপনি কোনও আদিম ধরণের তালিকায় যোগ করতে পারবেন না। পরিবর্তে ডিফল্টডিক্ট ব্যবহার করা আরও ভাল সমাধান।
ফখর মোকাদেমে

4
বিশেষভাবে, +কল __add__এবং আয় একটি নতুন বস্তু, যখন +=কল __iadd__, এবং একটি নতুন অবজেক্ট ফিরে যাওয়ার প্রয়োজন হয় না
njzk2

8

সমস্যাটি ব্যবহার করছে one_groups = dict.fromkeys(range(5), [])

(এটি সমস্ত কীতে মান হিসাবে একই তালিকাটি পাস করে So সুতরাং আপনি যদি একটি মান পরিবর্তন করেন তবে আপনি সেগুলি সমস্ত পরিবর্তন করেন)


পরিবর্তে আপনি এটি ব্যবহার করতে পারেন: one_groups = {i:[] for i in range(5)}

(এই জিনিসটি "চালিত" করবে] [] (যা প্রতিটি কী জন্য তালিকার সাথে সমান ()), এইভাবে বিভিন্ন তালিকার সাথে মান তৈরি করে)


6
আপনি একেবারে সঠিক, যদিও একটি ব্যাখ্যা সত্যিই সহায়ক হবে। দুটি লাইনের মধ্যে পার্থক্য কী তা সত্যই উদাসীন নয়।
সাইমন ফিংক

হ্যাঁ, এটা আমার খারাপ। দুঃখিত
Hameda169

4

এটি ডিকের fromkeysপদ্ধতিতে সহায়তা।

অন্তর্নির্মিত ফাংশন থোকায়সে সহায়তা:

বিল্টইনস টাইপ দৃষ্টান্তের পদ্ধতি (পুনরাবৃত্ত, মান = কোনওটি নয়, /) পদ্ধতি পুনরাবৃত্ত থেকে কীগুলি এবং মানকে মান হিসাবে সেট করে একটি নতুন অভিধান তৈরি করুন

এটি বলে যে থোকিরা কোনও মান গ্রহণ করবে এবং এটি কলযোগ্যও, এটি প্রথমে এটি মূল্যায়ন করবে এবং তারপরে সমস্ত মান ডিক কীগুলিতে সেই মান নির্ধারণ করবে।

পাইথনে তালিকাগুলি পরিবর্তনযোগ্য এবং তাই এটি একই খালি তালিকার রেফারেন্স নির্ধারণ করবে এবং একটি পরিবর্তন তাদের সমস্তকে প্রভাবিত করবে।

এর পরিবর্তে ডিফল্টডিক্টিক্ট ব্যবহার করুন:

>>> from collections import defaultdict
>>> one_groups = defaultdict(list)
>>> for x in binaries:
      one_groups[x.count('1')] += [x]
>>> one_groups = dict(one_groups) # to stop default dict behavior

এটি অ-বিদ্যমান কীগুলিতে অ্যাসাইনমেন্ট গ্রহণ করবে এবং মানগুলি খালি তালিকায় ডিফল্ট হবে (এই ক্ষেত্রে)।

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