পাইথন ৩.6++-তে অভিধানের অর্ডার দেওয়া আছে?


466

পূর্ববর্তী অবতারগুলির তুলনায় পাইথন ৩.6 (অন্তত সিপিথন বাস্তবায়নের আওতায়) অভিধানের অর্ডার দেওয়া হয়েছে। এটি যথেষ্ট পরিবর্তন হিসাবে মনে হয় তবে এটি ডকুমেন্টেশনের একটি সংক্ষিপ্ত অনুচ্ছেদ । এটি ভাষার বৈশিষ্ট্যের পরিবর্তে সিপিথন বাস্তবায়ন বিশদ হিসাবে বর্ণনা করা হয়েছে, তবে ভবিষ্যতে এটি স্ট্যান্ডার্ডও হতে পারে বলে বোঝায়।

এলিমেন্ট অর্ডার সংরক্ষণের সময় কীভাবে নতুন ডিকশনারি বাস্তবায়ন পুরানোটির চেয়ে ভাল সম্পাদন করতে পারে?

ডকুমেন্টেশন থেকে পাঠ্য এখানে:

dict()পাইপাই দ্বারা প্রবর্তিত এখন একটি "কমপ্যাক্ট" উপস্থাপনা ব্যবহার করা হয়েছে । নতুন ডিকের () স্মৃতি ব্যবহার পাইথন 3.5 এর তুলনায় 20% থেকে 25% এর মধ্যে ছোট। পিইপি 468 (একটি ফাংশনে ** কোয়ার্গের ক্রম সংরক্ষণ করে)) এটি প্রয়োগ করে। এই নতুন বাস্তবায়নের ক্রম-সংরক্ষণের দিকটি একটি বাস্তবায়নের বিশদ হিসাবে বিবেচিত হয় এবং এর উপর নির্ভর করা উচিত নয় (এটি ভবিষ্যতে পরিবর্তিত হতে পারে, তবে ভাষাটির বৈশিষ্ট্য পরিবর্তন করার আগে কয়েকটি নতুন প্রকাশের জন্য ভাষায় এই নতুন ডিক প্রয়োগকরণের ইচ্ছা রয়েছে) সমস্ত বর্তমান এবং ভবিষ্যতের পাইথন বাস্তবায়নের জন্য অর্ডার-সংরক্ষণের শব্দার্থকে ম্যান্ডেট করতে; এটি ভাষাটির পুরানো সংস্করণগুলির সাথে পিছনে-সামঞ্জস্যতা রক্ষা করতে সহায়তা করে যেখানে এলোমেলো পুনরাবৃত্তি আদেশ এখনও কার্যকর রয়েছে, যেমন পাইথন 3.5)। (ইনডা নওকি ইন অবদানইস্যু 27350 । আইডিয়াটি মূলত রেমন্ড হেট্টিংগার দ্বারা প্রস্তাবিত )

ডিসেম্বর 2017 আপডেট করুন: পাইথন 3.7 dictএর রক্ষণাবেক্ষণ সন্নিবেশ ক্রমের গ্যারান্টিযুক্ত


2
পাইথন- ডেভেল মেইলিং-লিস্টে এই থ্রেডটি দেখুন: mail.python.org/pipermail/python-dev/2016- সেপ্টেম্বর / 146327.html যদি আপনি এটি না দেখে থাকেন; এটি মূলত এই বিষয়গুলি নিয়ে আলোচনা।
এমজিসি

1
যদি এখন কোয়ার্গার্সকে অর্ডার করার কথা বলা হয় (যা দুর্দান্ত ধারণা) এবং কোয়ার্গস ডিক, অর্ডারডিক্ট না হয়ে থাকে, তবে আমি অনুমান করি যে ডাইম কীগুলি পাইথনের ভবিষ্যতের সংস্করণে অর্ডার থাকবে, ডকুমেন্টেশন অন্যথায় বলে না।
দিমিত্রি সিন্টসভ 12'17

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

7
রেমন্ড হেট্টিংগার
এলেক্স

1
@ ওয়াজিক্স, হ্যাশম্যাপের ক্রম ও জটিলতা পরিবর্তন হয়নি। পরিবর্তনটি কম স্থান নষ্ট করে হ্যাশম্যাপকে আরও ছোট করে তোলে এবং সহায়তার অ্যারের তুলনায় সংরক্ষিত স্থানটি (সাধারণত?) বেশি হয়। দ্রুততর, আরও ছোট, অর্ডার দেওয়া - আপনি সমস্ত 3 বেছে
নেবেন

উত্তর:


510

পাইথন ৩.6++-তে অভিধানের অর্ডার দেওয়া আছে?

তারা সন্নিবেশ আদেশ করা হয় [1] । পাইথন 3.6 এর হিসাবে, পাইথন এর CPython বাস্তবায়নের, অভিধান সন্নিবেশিত আইটেম অর্ডার স্মরণএটি পাইথন ৩.6 এ প্রয়োগের বিশদ হিসাবে বিবেচিত হয় ; পাইথনের অন্যান্য বাস্তবায়ন (এবং অন্যান্য আদেশযুক্ত আচরণ [1] ) জুড়ে গ্যারান্টযুক্তOrderedDict সন্নিবেশ ক্রম চাইলে আপনাকে ব্যবহার করতে হবে ।

পাইথন ৩.7 অনুসারে , এটি আর বাস্তবায়নের বিশদ নয় এবং পরিবর্তে এটি ভাষা বৈশিষ্ট্যে পরিণত হয়। জিভিআরের একটি অজগর-দেব বার্তা থেকে :

তেমনই করে ফেলো. "ডিক্ট সন্নিবেশের আদেশ রাখে" এই রায়। ধন্যবাদ!

এর সহজ অর্থ হ'ল আপনি এটির উপর নির্ভর করতে পারেন । পাইথনের অন্যান্য বাস্তবায়নগুলিতে অবশ্যই পাইথন ৩.7 এর যথাযথ বাস্তবায়ন হতে চাইলে অবশ্যই একটি সন্নিবেশ আদেশ আদেশ দেওয়া উচিত।


উপাদান অর্ডার সংরক্ষণের সময় পাইথন 3.6অভিধান প্রয়োগকরণ কীভাবে পুরানোটির চেয়ে ভাল [2] সম্পাদন করতে পারে?

মূলত, দুটি অ্যারে রেখে

  • প্রথম অ্যারে, অভিধানের জন্য dk_entriesএন্ট্রি ( টাইপPyDictKeyEntry ) ধারণ করে যাতে তারা inোকানো হয়েছিল। সংরক্ষণের অর্ডারটি কেবলমাত্র একটি সংযোজন অ্যারে হয়েই পাওয়া যায় যেখানে সর্বদা নতুন আইটেমগুলি সন্নিবেশ করা হয় (সন্নিবেশ ক্রম)।

  • দ্বিতীয়টি, অ্যারের dk_indicesসূচকগুলি ধরে রাখে dk_entries(এটি হল মানগুলি যা সংশ্লিষ্ট প্রবেশের অবস্থান নির্দেশ করে dk_entries)। এই অ্যারে হ্যাশ টেবিল হিসাবে কাজ করে। একটি কী হ্যাশ করা হয় এটি সঞ্চিত সূচকগুলির একটির দিকে নিয়ে যায় এবং আনুষাঙ্গিক dk_indicesঅনুসারে সংশ্লিষ্ট এন্ট্রিটি আনা হয় dk_entries। যেহেতু কেবল সূচকগুলি রাখা হয়, তাই এই অ্যারের ধরণটি অভিধানের সামগ্রিক আকারের উপর নির্ভর করে (টাইপ int8_t( 1বাইট) থেকে int32_t/ int64_t( 4/ 8বাইট) 32/ 64বিট বিল্ডস পর্যন্ত)

পূর্ববর্তী বাস্তবায়নে, প্রকার PyDictKeyEntryও আকারের একটি বিচ্ছিন্ন অ্যারে dk_sizeবরাদ্দ করতে হয়েছিল; দুর্ভাগ্যবশত, এটি খালি স্থান অনেক ফলে যেহেতু যে অ্যারের বেশী হতে দেওয়ার অনুমতি দেওয়া হয়নি 2/3 * dk_sizeপূর্ণ কর্মক্ষমতা কারণে । (এবং খালি জায়গার এখনওPyDictKeyEntry আকার ছিল !)।

এটি এখনকার ক্ষেত্রে নয় কারণ কেবলমাত্র প্রয়োজনীয় এন্ট্রিগুলি সঞ্চিত রয়েছে (সেগুলি সন্নিবেশ করা হয়েছে) এবং প্রকারের একটি স্পারস অ্যারে intX_t( Xডিক আকারের উপর নির্ভর করে) 2/3 * dk_sizeপূর্ণ রাখে। খালি জায়গাটি টাইপ থেকে পরিবর্তিত PyDictKeyEntryহয়েছে intX_t

সুতরাং, স্পষ্টতই, একটি বিচ্ছিন্ন অ্যারে তৈরি করা ধরণের PyDictKeyEntryস্টোরের জন্য একটি বিচ্ছিন্ন অ্যারের চেয়ে অনেক বেশি মেমরির দাবি int

আগ্রহী যদি এই বৈশিষ্ট্যটি সম্পর্কিত আপনি পাইথন-ডেভের সম্পূর্ণ কথোপকথনটি দেখতে পারেন তবে এটি ভাল পড়া is


রেমন্ড হেট্টিংগার দ্বারা নির্মিত মূল প্রস্তাবনায় , ব্যবহৃত ডেটা স্ট্রাকচারের একটি ভিজ্যুয়ালাইজেশন দেখা যায় যা ধারণাটির সূত্র ধরে capt

উদাহরণস্বরূপ, অভিধান:

d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}

বর্তমানে [কীহ্যাশ, কী, মান] হিসাবে সংরক্ষণ করা হয়েছে:

entries = [['--', '--', '--'],
           [-8522787127447073495, 'barry', 'green'],
           ['--', '--', '--'],
           ['--', '--', '--'],
           ['--', '--', '--'],
           [-9092791511155847987, 'timmy', 'red'],
           ['--', '--', '--'],
           [-6480567542315338377, 'guido', 'blue']]

পরিবর্তে, ডেটা নিম্নলিখিত হিসাবে সংগঠিত করা উচিত:

indices =  [None, 1, None, None, None, 0, None, 2]
entries =  [[-9092791511155847987, 'timmy', 'red'],
            [-8522787127447073495, 'barry', 'green'],
            [-6480567542315338377, 'guido', 'blue']]

আপনি এখন দৃশ্যমান হিসাবে দেখতে পাচ্ছেন, মূল প্রস্তাবনায়, সংঘর্ষ হ্রাস করতে এবং চেহারা দ্রুত তৈরি করার জন্য প্রচুর জায়গা মূলত খালি। নতুন পদ্ধতির সাহায্যে, সূচকগুলিতে, যেখানে সত্যই এটি প্রয়োজন সেখানে স্নেহ সরিয়ে আপনি প্রয়োজনীয় স্মৃতি হ্রাস করেন।


[1]: আমি বলি "সন্নিবেশের আদেশ" এবং অর্ডারডিক্টের অস্তিত্বের সাথে "অর্ডার করা" নয়, "অর্ডার করা" আরও এমন আচরণের পরামর্শ দেয় যা dictঅবজেক্টটি সরবরাহ করে না । অর্ডারডিক্টসগুলি বিপরীতমুখী হয়, অর্ডার সংবেদনশীল পদ্ধতি সরবরাহ করে এবং মূলত অর্ডার-সংবেদনশীল সমতা পরীক্ষা দেয় ( ==, !=)। dictএর বর্তমানে সেই আচরণ / পদ্ধতিগুলির কোনও অফার করে না।


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

সামগ্রিকভাবে, অভিধানের পারফরম্যান্স, বিশেষত বাস্তব জীবনের পরিস্থিতিতে, সংক্ষিপ্ততার পরিচয় হওয়ার কারণে উন্নতি হয়।


15
সুতরাং, যখন কোনও আইটেম সরানো হবে তখন কী ঘটে? হয় entriesতালিকা মাপ পরিবর্তন? বা ফাঁকা জায়গা রাখা আছে? বা এটি সময়ে সময়ে সংকুচিত হয়?
njzk2

18
@ njzk2 যখন কোনও আইটেম সরিয়ে ফেলা হয়, তখন সংশ্লিষ্ট সূচকটি DKIX_DUMMYএকটি মান দিয়ে প্রতিস্থাপিত হয় -2এবং entryঅ্যারেতে প্রবেশের পরিবর্তেNULL সন্নিবেশ করা হয়, যখন সন্নিবেশ সম্পাদন করা হয় তখন প্রবেশকারী অ্যারেতে নতুন মান সংযোজন করা হয়, এখনও সনাক্ত করতে সক্ষম হয় নি, তবে সূচকগুলি যখন 2/3প্রান্তিকের আকার পরিবর্তন করে তখন পুনরায় আকার দেওয়া হয়। এটি অনেক DUMMYএন্ট্রি বিদ্যমান থাকলে এটি বাড়ার পরিবর্তে সঙ্কুচিত হতে পারে।
দিমিত্রিস ফাসারাকিস হিলিয়ার্ড

3
@Chris_Rands না, শুধুমাত্র প্রকৃত রিগ্রেশন আমি দেখেছি একটি যে ব্যক্তি অনুসরণ করে হয় ভিক্টর দ্বারা বার্তা । সেই মাইক্রোব্যাঙ্কমার্ক ব্যতীত, আমি অন্য কোনও সমস্যা / বার্তা দেখেছি যা বাস্তব জীবনের কাজের বোঝায় গুরুতর গতির পার্থক্য নির্দেশ করে। এমন জায়গাগুলি রয়েছে যেখানে নতুন ডিকটি সামান্য রিগ্রেশনগুলি (উদাহরণস্বরূপ কী-লকআপস) প্রবর্তন করতে পারে যখন অন্যদের মধ্যে (পুনরাবৃত্তি এবং পুনরায় আকার দেওয়ার বিষয়টি মাথায় আসে) একটি পারফরম্যান্স বুস্ট উপস্থিত থাকবে।
দিমিত্রিস ফাসারাকিস হিলিয়ার্ড

3
আকার পরিবর্তনকারী অংশে সংশোধন : আপনি যখন আইটেমগুলি মুছবেন তখন অভিধানগুলি পুনরায় আকার দেয় না, যখন আপনি পুনরায় প্রবেশ করান তখন সেগুলি পুনরায় গণনা করে। সুতরাং, যদি কোনও ডিক তৈরি করা হয় d = {i:i for i in range(100)}এবং আপনি .popসমস্ত আইটেম ডাব্লু / ও .োকানো হয় তবে আকার পরিবর্তন হবে না। আপনি যখন এটিতে আবার যুক্ত করেন, d[1] = 1উপযুক্ত আকারটি গণনা করা হয় এবং ডকের আকার পরিবর্তন করে।
দিমিত্রিস ফাসারাকিস হিলিয়ার্ড

6
@ ক্রিস_আর্যান্ডস আমি নিশ্চিত যে এটি থাকছে। বিষয়টি হ'ল এবং ' dictআদেশ দেওয়া' সম্পর্কে কম্বল বিবৃতি অপসারণের জন্য কেন আমি আমার উত্তর পরিবর্তন করেছি , dictসেগুলি অর্থে অর্ডার করা হয়নি OrderedDict। উল্লেখযোগ্য বিষয়টি সমতা। dictএর অর্ডার সংবেদনশীল রয়েছে ==, OrderedDictএর অর্ডার সংবেদনশীল রয়েছে। OrderedDictগুলি ডাম্পিং করা এবং dictsএখনই অর্ডার সংবেদনশীল তুলনা করা পরিবর্তনের ফলে পুরানো কোডটিতে প্রচুর ভাঙন দেখা দিতে পারে। আমি অনুমান করছি একমাত্র জিনিস যা OrderedDictএর সম্পর্কে পরিবর্তন হতে পারে তা হ'ল এর বাস্তবায়ন।
দিমিত্রিস ফাসারাকিস হিলিয়ার্ড

66

নীচে মূল প্রথম প্রশ্নের উত্তর দেওয়া হচ্ছে:

আমি ব্যবহার করা উচিত dictবা OrderedDictপাইথন 3.6 মধ্যে?

আমি মনে করি ডকুমেন্টেশন থেকে এই বাক্যটি আপনার প্রশ্নের উত্তর দেওয়ার জন্য যথেষ্ট

এই নতুন বাস্তবায়নের অর্ডার-সংরক্ষণের দিকটি একটি বাস্তবায়ন বিশদ হিসাবে বিবেচিত হয় এবং এর উপর নির্ভর করা উচিত নয়

dictস্পষ্টভাবে আদেশ সংগ্রহে হতে চাইলে আমাদের অবশ্যই সামঞ্জস্যপূর্ণ থাকতে চাই এবং নতুন বাস্তবায়ন আপনার সাথে বিদ্ধ করা উচিত একটি পার্শ্ব প্রতিক্রিয়া উপর নির্ভর করে না তাই যদি বোঝানো হয় না OrderedDict

আপনার কোড ভবিষ্যতের প্রমাণ করুন :)

এখানে সে সম্পর্কে একটি বিতর্ক আছে

সম্পাদনা করুন: পাইথন 3.7 একটি বৈশিষ্ট্য হিসাবে এই রাখা হবে দেখুন


1
দেখে মনে হচ্ছে যে তারা যদি এটিকে একটি আসল বৈশিষ্ট্য হিসাবে না বোঝায় তবে কেবল একটি বাস্তবায়ন বিশদ হয় তবে তাদের এমনকি এটি তখন নথির মধ্যে রাখা উচিত নয়।
xji

3
আমি আপনার সম্পাদনা সাবধান সম্পর্কে নিশ্চিত নই; যেহেতু গ্যারান্টিটি কেবল পাইথন ৩.7-এর জন্য প্রযোজ্য তাই আমি ধরে নিয়েছি পাইথন ৩.6-এর পরামর্শটি অপরিবর্তিত রয়েছে, অর্থাত
সিপিথনে ডিক্টস অর্ডার

25

আপডেট: গাইডো ভ্যান রসম মেলিং তালিকায় ঘোষণা করেছিলেন যে dictসমস্ত পাইথন বাস্তবায়নের মধ্যে পাইথন ৩.7 এস অবশ্যই প্রবেশের ক্রম সংরক্ষণ করবে।


2
এখন যে কী অর্ডারিংটি অফিশিয়াল স্ট্যান্ডার্ড, অর্ডারডিক্টের উদ্দেশ্য কী? বা, এটি কি এখন অপ্রয়োজনীয়?
জনি ওয়াফলস

2
আমার ধারণা অর্ডারডিক্ট রিডানডান্ট হবে না কারণ এর move_to_endপদ্ধতি রয়েছে এবং এর সাম্যতাটি অর্ডার সংবেদনশীল: ডকস.পাইথন.আর / 3 / লিবারি / … জিম ফাসারাকিস হিলিয়ার্ডের উত্তরে নোটটি দেখুন।
fjsj

@JonnyWaffles জিম এর উত্তর এবং এই Q & A- দেখতে stackoverflow.com/questions/50872498/...
Chris_Rands

3
আপনি যদি নিজের কোডটি 2.7 এবং 3.6 / 3.7 + তে একইভাবে চালাতে চান তবে আপনাকে অর্ডারডিক্ট
বোটকোডার

3
সম্ভবত লোকেরা যারা সুরক্ষার কারণে তাদের
ডিক্টগুলি

9

আমি উপরের আলোচনায় যুক্ত করতে চেয়েছিলাম তবে মন্তব্য করার খ্যাতি নেই।

পাইথন ৩.৮ এখনও প্রকাশিত হয় নি তবে এটি reversed()অভিধানে ফাংশনটি অন্তর্ভুক্ত করবে (এর থেকে অন্য একটি পার্থক্য অপসারণ করে) OrderedDict

বিবর্তিত সন্নিবেশ ক্রমে বিপরীত () ব্যবহার করে ডিক্ট এবং ডিকমিউজগুলি এখন পুনরাবৃত্তিযোগ্য। (বিপিও -৩৩৪62২ তে রামি লাপেয়ারের দ্বারা অবদানিত।) অজগর ৩.৮ এ দেখুন কী

সাম্য অপারেটর বা অন্যান্য বৈশিষ্ট্যগুলির কোনও উল্লেখ আমি দেখতে পাচ্ছি না OrderedDictতারা এখনও সম্পূর্ণরূপে এক নয়।

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