অভিধান দেখুন অবজেক্ট কি?


158

অজগর ২.7-তে, আমরা অভিধান দেখার পদ্ধতি উপলব্ধ পেয়েছি ।

এখন, আমি নিম্নলিখিতগুলির প্রো ও কনসটি জানি:

  • dict.items()(এবং values, keys): একটি তালিকা দেয়, যাতে আপনি আসলে ফলাফল সংরক্ষণ করতে পারেন এবং
  • dict.iteritems() (এবং এর মতো): একটি জেনারেটর ফিরিয়ে দেয়, যাতে আপনি প্রতিটি মান একের পর এক উত্পন্ন করতে পারেন।

কি কি dict.viewitems()(এবং মত) জন্য? তাদের সুবিধা কি? এটা কিভাবে কাজ করে? সব পরে একটি ভিউ কি?

আমি পড়লাম যে ভিউ সর্বদা অভিধান থেকে পরিবর্তনগুলি প্রতিফলিত করে। তবে পারফ এবং স্মৃতি দৃষ্টিকোণ থেকে এটি কীভাবে আচরণ করে? প্রো এবং কনস কি?

উত্তর:


157

অভিধানের মতামতগুলি মূলত তাদের নাম যা বলে তা হ'ল: ভিউগুলি কোনও অভিধানের কী এবং মান (বা আইটেম) এর উইন্ডোর মতো । পাইথন 3 এর অফিসিয়াল ডকুমেন্টেশনের একটি অংশ এখানে দেওয়া হয়েছে :

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.keys()
>>> values = dishes.values()

>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> keys  # No eggs anymore!
dict_keys(['sausage', 'bacon', 'spam'])

>>> values  # No eggs value (2) anymore!
dict_values([1, 1, 500])

(পাইথন 2 সমতুল্য ব্যবহার dishes.viewkeys()এবং dishes.viewvalues()।)

এই উদাহরণটি দেখুনের গতিশীল চরিত্রটি দেখায় : কী দর্শনটি নির্দিষ্ট সময়ে নির্দিষ্ট সময়ে কীগুলির অনুলিপি নয় , বরং একটি সরল উইন্ডো যা আপনাকে কীগুলি দেখায়; যদি সেগুলি পরিবর্তন করা হয়, তবে আপনি উইন্ডোটির মাধ্যমে যা দেখেন তা পরিবর্তন হয়। এই বৈশিষ্ট্যটি কিছু পরিস্থিতিতে কার্যকর হতে পারে (উদাহরণস্বরূপ, প্রতিটি প্রোগ্রামের একাধিক অংশে কীগুলির সাথে একটি ভিউ নিয়ে কাজ করার জন্য বর্তমানের কীগুলি প্রয়োজন হবে প্রতিবারের তালিকাগুলির পরিবর্তে পুনরায় গণনা করা উচিত) - দ্রষ্টব্য যদি অভিধান কীগুলি সংশোধন করা হয় দৃশ্যের মাধ্যমে পুনরাবৃত্তি করার সময়, পুনরুক্তিকারীকে কীভাবে আচরণ করা উচিত তা ভালভাবে সংজ্ঞায়িত করা হয়নি, যা ত্রুটির দিকে পরিচালিত করতে পারে

একটি সুবিধা যে খুঁজছেন বলুন, কী ব্যবহারসমূহ শুধুমাত্র এ মেমরি ক্ষুদ্র ও নির্দিষ্ট পরিমাণ এবং প্রয়োজন প্রসেসর সময় একটি ছোট এবং নির্দিষ্ট পরিমাণ , অপরপক্ষে পাইথন 2, সেখানে কী একটি তালিকা কোন সৃষ্টি ( রাজেন্দ্রন টি দ্বারা উদ্ধৃত হিসাবে অযথা প্রায়ই একটি নতুন তালিকা তৈরি করে, যা তালিকার দৈর্ঘ্যের সাথে আনুপাতিক পরিমাণে স্মৃতি এবং সময় নেয়)। উইন্ডো সাদৃশ্য চালিয়ে যেতে, আপনি যদি কোনও দেয়ালের পিছনে ল্যান্ডস্কেপ দেখতে চান তবে আপনি কেবল এটিতে একটি উদ্বোধন করেন (আপনি উইন্ডোটি তৈরি করেন); কীগুলিকে একটি তালিকায় অনুলিপি করা তার পরিবর্তে আপনার প্রাচীরের ল্যান্ডস্কেপের একটি অনুলিপি আঁকার সাথে মিলে যাবে — অনুলিপি সময়, স্থান নেয় এবং নিজে আপডেট হয় না।

সংক্ষিপ্তসার হিসাবে, দর্শনগুলি আপনার অভিধানে কেবলমাত্র ... ভিউ (উইন্ডোজ) হয়, যা অভিধানের পরিবর্তিত হওয়ার পরেও বিষয়বস্তু প্রদর্শন করে। তারা তালিকাগুলির থেকে পৃথক বৈশিষ্ট্যগুলি সরবরাহ করে: কীগুলির তালিকায় একটি নির্দিষ্ট সময়ে ডিকশনারি কীগুলির একটি অনুলিপি থাকে , যখন একটি দৃশ্য গতিশীল হয় এবং এটি পেতে খুব দ্রুত হয়, কারণ এতে কোনও ডেটা অনুলিপি করতে হয় না ( কী বা মান) তৈরি করার জন্য।


6
+1 টি। ঠিক আছে, কীগুলির অভ্যন্তরীণ তালিকায় সরাসরি অ্যাক্সেস থাকা থেকে এটি কীভাবে আলাদা? এটা কি দ্রুত, ধীর? আরও স্মৃতি দক্ষ? সীমাবদ্ধ? আপনি যদি এটি পড়তে এবং সম্পাদনা করতে পারেন তবে এটি এই তালিকার রেফারেন্স থাকার মতোই অনুভূত হয়।
ই-সন্তুষ্ট

3
ধন্যবাদ। জিনিস যে মতামত হল হয় "কি অভ্যন্তরীণ তালিকা" আপনার অ্যাক্সেস (নোট যে এই "কি তালিকা" একটি পাইথন তালিকা, যদিও নয়, কিন্তু অবিকল একটি দৃশ্য যায়)। পাইথন 2 এর কী (বা মান বা আইটেম) তালিকার চেয়ে ভিউগুলি আরও মেমরি দক্ষ, যেহেতু তারা কোনও কিছুই অনুলিপি করে না; তারা প্রকৃতপক্ষে "কীগুলির তালিকার একটি রেফারেন্স" এর মতো (নোট করুন যে "তালিকার কোনও রেফারেন্স" আসলে পাইথন-এ কেবল একটি তালিকা বলা হয়, কারণ তালিকাগুলি পরিবর্তনীয় বস্তু) are এছাড়াও নোট করুন যে আপনি সরাসরি দর্শন সম্পাদনা করতে পারবেন না: পরিবর্তে, আপনার এখনও অভিধান সম্পাদনা করুন এবং দর্শনগুলি তত্ক্ষণাত আপনার পরিবর্তনগুলি প্রতিবিম্বিত করে।
এরিক হে লেবিগোট

3
ঠিক আছে, আমি এখনও বাস্তবায়ন সম্পর্কে পরিষ্কার নয়, তবে এটি এখন পর্যন্ত সেরা উত্তর answer
ই-সন্তুষ্ট 22'12

2
ধন্যবাদ। প্রকৃতপক্ষে, এই উত্তরটি বেশিরভাগ মতামতের শব্দার্থ সম্পর্কে । সিপিথনে তাদের বাস্তবায়ন সম্পর্কে আমার কাছে তথ্য নেই তবে আমি অনুমান করব যে একটি ভিউ মূলত সঠিক কাঠামোর (কী) এবং কী বা / অথবা মানগুলির পয়েন্টার এবং কাঠামোগুলি নিজেই অভিধান অবজেক্টের অংশ।
এরিক হে লেবিগোট

5
আমি মনে করি যে এই পোস্টে উদাহরণ কোডটি পাইথন 3 থেকে পাওয়া যায় এবং পাইথন 2.7 এ আমি পাই না।
snth

21

যেমনটি আপনি উল্লেখ করেছেন dict.items()যে অভিধানের (কী, মান) dict.iteritems()জোড়গুলি অপ্রয়োজনীয় তালিকার একটি অনুলিপি প্রদান করে এবং অভিধানের (কী, মান) জোড়গুলির মধ্যে একটি পুনরাবৃত্তিকে ফেরত দেয়।

ডেকের একটি ইন্টারেক্টর এবং ডিকের দৃষ্টিভঙ্গির মধ্যে পার্থক্য দেখতে এখন নীচের উদাহরণটি ধরুন

>>> d = {"x":5, "y":3}
>>> iter = d.iteritems()
>>> del d["x"]
>>> for i in iter: print i
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

যদিও একটি ভিউ সহজভাবে আপনাকে ডিকটিতে কী দেখায়। এটি পরিবর্তিত হয় কিনা তা বিবেচ্য নয়:

>>> d = {"x":5, "y":3}
>>> v = d.viewitems()
>>> v
dict_items([('y', 3), ('x', 5)])
>>> del d["x"]
>>> v
dict_items([('y', 3)])

অভিধানটি এখন দেখার মতো দেখতে একটি ভিউ। একটি এন্ট্রি মুছে ফেলার পরে পুরানো ছিল .items()এবং .iteritems()একটি ত্রুটি নিক্ষেপ করা হবে।


দুর্দান্ত উদাহরণ, ধন্যবাদ। যদিও, v = d.items () হওয়া উচিত নয় v - d.viewitems ()
রিক্স

1
প্রশ্নটি পাইথন ২.7 সম্পর্কে, সুতরাং viewitems()প্রকৃতপক্ষে সঠিক ( items()সঠিকভাবে পাইথন 3 এ একটি ভিউ দেয় )।
এরিক ও লেবিগোট

যাইহোক, একটি দৃশ্য করতে পারবে না একটি অভিধান পুনরুক্তি উপর যখন এটি পরিবর্তন ব্যবহৃত হবে না।
আইওনিস ফিলিপিসিস

18

ডক্সটি পড়েই আমি এই ধারণাটি পেয়েছি:

  1. ভিউগুলি "সিউডো-সেট-লাইক", যাতে তারা ইনডেক্সিং সমর্থন করে না, তাই আপনি তাদের সাথে যা করতে পারেন তা সদস্যতার জন্য পরীক্ষা করা এবং তাদের উপরে পুনরাবৃত্তি করা (কারণ কীগুলি হ্যাশযোগ্য এবং অনন্য, কীগুলি এবং আইটেমের ভিউ আরও বেশি " সেট-মত "এতে তারা সদৃশ থাকে না)।
  2. আপনি সেগুলি সঞ্চয় করতে পারেন এবং তালিকার সংস্করণগুলির মতো এগুলি একাধিকবার ব্যবহার করতে পারেন।
  3. যেহেতু তারা অন্তর্নিহিত অভিধানকে প্রতিফলিত করে তাই অভিধানের যে কোনও পরিবর্তনই দৃষ্টিভঙ্গি বদলে দেবে এবং অবশ্যই অবশ্যই পুনরাবৃত্তির ক্রম পরিবর্তন করবে । সুতরাং তালিকার সংস্করণগুলির বিপরীতে, তারা "স্থিতিশীল" নয়।
  4. যেহেতু তারা অন্তর্নিহিত অভিধানকে প্রতিফলিত করে, তারা প্রায় অবশ্যই ছোট প্রক্সি বস্তু; কী / মান / আইটেমগুলি অনুলিপি করার জন্য তারা মূল অভিধানটি কোনওভাবে পর্যবেক্ষণ করতে হবে এবং পরিবর্তনগুলি ঘটে যখন একাধিকবার এটি অনুলিপি করে থাকে যা একটি অযৌক্তিক বাস্তবায়ন হবে। সুতরাং আমি খুব কম মেমরির ওভারহেডের আশা করব, তবে সরাসরি অভিধানের তুলনায় অ্যাক্সেসটি একটু ধীর হতে হবে।

সুতরাং আমি অনুমান করি কী ব্যবহারটি হ'ল যদি আপনি একটি অভিধান রাখে এবং তার চাবি / আইটেম / মানগুলির মধ্যে পরিবর্তনগুলির সাথে বার বার পুনরাবৃত্তি করেন। আপনি শুধু পরিবর্তে একটি দৃশ্য ব্যবহার করতে পারে, বাঁক for k, v in mydict.iteritems():মধ্যে for k, v in myview:। তবে আপনি যদি একবার অভিধানে পুনরাবৃত্তি করেন তবে আমি মনে করি যে এটির সংস্করণগুলি আরও ভাল।


2
আমাদের পাওয়া কয়েকটি তথ্য থেকে প্রো ও কনস বিশ্লেষণের জন্য +1 +
ই-সন্তুষ্ট

যদি আমি একটি দৃশ্যের উপর দিয়ে একটি পুনরাবৃত্তি তৈরি করি তবে ডিকশনারিটি পরিবর্তন হয়ে গেলেও এটি অবৈধ হয়ে যায়। ডিকশনারি নিজেই (যেমন iteritems()) একটি পুনরাবৃত্তিকারী হিসাবে একই সমস্যা । সুতরাং এই মতামত এর বিন্দু কি? এগুলি পেয়ে আমি কখন খুশি?
আলফ

@ আলফ আপনি ঠিকই বলেছেন, অভিধানের পুনরাবৃত্তির ক্ষেত্রে এটি একটি সমস্যা এবং দর্শনগুলি এটিকে মোটেই সহায়তা করে না। বলুন আপনাকে কোনও ফাংশনে অভিধানের মানগুলি পাস করতে হবে। আপনি ব্যবহার করতে পারেন .values(), তবে এর মধ্যে একটি তালিকা হিসাবে সম্পূর্ণ অনুলিপি তৈরি করা জড়িত, যা ব্যয়বহুল হতে পারে। রয়েছে .itervalues()তবে আপনি এগুলি একাধিকবার গ্রাস করতে পারবেন না, সুতরাং এটি প্রতিটি ফাংশন দিয়ে কাজ করবে না। দর্শনগুলির জন্য ব্যয়বহুল অনুলিপিের প্রয়োজন নেই, তবে তারা পুনরুক্তির চেয়ে একক স্ট্যান্ড মান হিসাবে এখনও বেশি কার্যকর। তবে তারা একই সময়ে পুনরাবৃত্তি এবং সংশোধন করতে সহায়তা করার উদ্দেশ্যে নয় (সেখানে আপনি সত্যিই একটি অনুলিপি চান)।
বেন

17

দেখার পদ্ধতিগুলি একটি তালিকা ফেরত দেয় (তালিকার অনুলিপি নয় .keys(), .items()এবং এর তুলনায় .values()), সুতরাং এটি আরও বেশি ওজনের, তবে অভিধানের বর্তমান বিষয়বস্তুগুলি প্রতিবিম্বিত করে।

পাইথন ৩.০ থেকে - ডিক পদ্ধতিগুলি পুনরায় দেখা - কেন?

মূল কারণ হ'ল অনেক ব্যবহারের ক্ষেত্রে সম্পূর্ণ বিচ্ছিন্ন তালিকার ফিরিয়ে দেওয়া অপ্রয়োজনীয় এবং অপব্যয়যোগ্য। এর জন্য সম্পূর্ণ সামগ্রীর অনুলিপি করা প্রয়োজন (যা অনেকের বেশি নাও হতে পারে)।

আপনি যদি কীগুলি দিয়ে পুনরাবৃত্তি করতে চান তবে একটি নতুন তালিকা তৈরি করা প্রয়োজনীয় নয়। এবং যদি সত্যিই আপনার এটির আলাদা তালিকা (অনুলিপি হিসাবে) প্রয়োজন হয় তবে আপনি সহজেই ভিউ থেকে সেই তালিকাটি তৈরি করতে পারেন।


6
দেখার পদ্ধতিগুলি ভিউ অবজেক্টগুলি ফেরত দেয় যা তালিকার ইন্টারফেসের সাথে খাপ খায় না।
ম্যাথু ট্রেভর

5

দর্শনগুলি আপনাকে অনুলিপি করা তথ্য কাঠামো অনুলিপি ছাড়াই অ্যাক্সেস করতে দেয়। একটি তালিকা তৈরির বিরোধী হিসাবে গতিশীল হওয়ার পাশাপাশি, তাদের সর্বাধিক দরকারী ব্যবহারের একটি হচ্ছে inপরীক্ষা। বলুন যে আপনি মানটি ডিকের মধ্যে আছে কিনা তা পরীক্ষা করতে চান (হয় তা কী বা মান হতে পারে)।

বিকল্পগুলির মধ্যে একটিটি কী ব্যবহার করে কীগুলির একটি তালিকা তৈরি করা হয় dict.keys(), এটি কাজ করে তবে স্পষ্টতই বেশি মেমরি গ্রহণ করে। ডিক খুব বড় হলে? এটা অপচয় হবে।

সঙ্গে viewsআপনি প্রকৃত তথ্য-কাঠামো পুনরুক্তি করতে পারেন, অন্তর্বর্তী তালিকা ছাড়াই।

এর উদাহরণ ব্যবহার করা যাক। আমি এলোমেলো স্ট্রিং এবং ডিজিটের 1000 কীগুলির সাথে একটি ডিক করেছি এবং kআমি কীটি সন্ধান করতে চাই তা হল

large_d = { .. 'NBBDC': '0RMLH', 'E01AS': 'UAZIQ', 'G0SSL': '6117Y', 'LYBZ7': 'VC8JQ' .. }

>>> len(large_d)
1000

# this is one option; It creates the keys() list every time, it's here just for the example
timeit.timeit('k in large_d.keys()', setup='from __main__ import large_d, k', number=1000000)
13.748743600954867


# now let's create the list first; only then check for containment
>>> list_keys = large_d.keys()
>>> timeit.timeit('k in list_keys', setup='from __main__ import large_d, k, list_keys', number=1000000)
8.874809793833492


# this saves us ~5 seconds. Great!
# let's try the views now
>>> timeit.timeit('k in large_d.viewkeys()', setup='from __main__ import large_d, k', number=1000000)
0.08828549011070663

# How about saving another 8.5 seconds?

যেমন আপনি দেখতে পাচ্ছেন, পুনরাবৃত্তি হওয়া viewঅবজেক্টটি একই সাথে মেমরির ওভারহেড হ্রাস করে, কর্মক্ষমতাকে বিশাল বৃদ্ধি দেয়। আপনার যখন Setঅপারেশনগুলির মতো সঞ্চালনের প্রয়োজন হয় তখন এগুলি ব্যবহার করা উচিত ।

দ্রষ্টব্য : আমি পাইথন ২.7 এ চলছে


পাইথন> = 3 এ, আমি বিশ্বাস করি .keys()ডিফল্টরূপে কোনও দৃশ্য ফেরত দেয়। দ্বিগুণ চেক করতে পারে
ইয়োলো ভো

1
তুমি ঠিক বলছো. পাইথন 3+ তালিকার পরিবর্তে ভিউ অবজেক্টগুলির ভারী ব্যবহার করে, এটি অনেক বেশি মেমরির দক্ষ
চেন এ।

1
এই সময়জ্ঞান ফলাফল খুব কহন হয়, কিন্তু চেক কিনা kঅভিধানের কি এক large_dসঙ্গে সম্পন্ন করা বোঝানো হয় k in large_dপাইথন, সম্ভবত মূলত হিসাবে দ্রুত (অন্য কথায় একটি দর্শন ব্যবহার হিসাবে, k in large_d.keys()Pythonic নয় এবং avoided- হওয়া উচিত যেমন k in large_d.viewkeys())।
এরিক হে লেবিগোট

একটি দৃ ,়, দরকারী উদাহরণ সরবরাহ করার জন্য আপনাকে ধন্যবাদ। k in large_dআসলে তুলনায় তাত্পর্যপূর্ণ দ্রুত k in large_d.viewkeys(), তাই সম্ভবত এড়ানো উচিত, কিন্তু এটি এর অর্থ দেয় k in large_d.viewvalues()
nnot101
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.