কীভাবে ঘোষিত হিসাবে কীগুলি / মানগুলি একই ক্রমে রাখবেন?


320

আমার একটি অভিধান রয়েছে যা আমি একটি নির্দিষ্ট ক্রমে ঘোষণা করেছি এবং এটি সারাক্ষণ সেই ক্রমে রাখতে চাই। কীগুলি / মানগুলি তাদের মানের উপর ভিত্তি করে যথাযথভাবে সংরক্ষণ করা যায় না, আমি কেবল এটি ক্রম হিসাবে ঘোষণা করেছি।

সুতরাং আমার যদি অভিধান থাকে:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

আমি এটি দেখতে বা এটির মাধ্যমে পুনরাবৃত্তি করা হলে এটি সেই ক্রমে নয়, পাইথন যে কীগুলি / মানগুলিতে আমি ঘোষণা করেছি তার স্পষ্ট ক্রমটি পাইথন পাবে কিনা তা নিশ্চিত করার কোনও উপায় আছে?

উত্তর:


229

পাইথন ৩.6 থেকে, স্ট্যান্ডার্ড dictটাইপ ডিফল্টরূপে সন্নিবেশ ক্রম বজায় রাখে।

সংজ্ঞা

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

উত্স কোডে তালিকাভুক্ত ক্রমের কীগুলির সাথে অভিধান তৈরি করবে।

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

3.6 এ এটি এখনও বাস্তবায়নের বিশদ হিসাবে বিবেচিত হয়েছিল; দেখতে নতুন কি পাইথন 3.6 মধ্যে ডকুমেন্টেশন :

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

পাইথন ৩.7 এই প্রয়োগকরণের বিশদটি একটি ভাষার স্পেসিফিকেশনে উন্নীত করে , তাই এটি এখন বাধ্যতামূলক যে dictসমস্ত পাইথন বাস্তবায়নের ক্ষেত্রে সেই সংস্করণ বা আরও নতুনের সাথে সামঞ্জস্যপূর্ণ order বিডিএফএল দ্বারা ঘোষণা দেখুন

আপনি এখনও কিছু ক্ষেত্রে collections.OrderedDict()ক্লাসটি ব্যবহার করতে চাইতে পারেন , কারণ এটি স্ট্যান্ডার্ড dictটাইপের উপরে কিছু অতিরিক্ত কার্যকারিতা সরবরাহ করে । যেমন বিপরীতমুখী হওয়া (এটি ভিউ অবজেক্টগুলিতে প্রসারিত ) এবং সমর্থন পুনরায় অর্ডারিং ( move_to_end()পদ্ধতিটির মাধ্যমে )।


দুর্ভাগ্যক্রমে এটি অভিধান তৈরির জন্য প্রাসঙ্গিক নয় । কোডে উদাহরণের মতো নির্দিষ্ট শব্দকোষগুলি একই ক্রম বজায় রাখার গ্যারান্টিযুক্ত নয়। এর অর্থ আপনি খালি ডিক তৈরি করতে হবে এবং আপনি যদি অর্ডারটি নিয়ন্ত্রণ করতে চান তবে প্রতিটি উপাদান ম্যানুয়ালি .োকাতে হবে।
nnot101

8
@ naught101: না, এই না অভি সৃষ্টি প্রযোজ্য। পাইথন ৩.7 এবং তার উপরে, প্রশ্নের মতো ডিক প্রদর্শন ব্যবহার করে সেই কীগুলি যথাযথভাবে তালিকাভুক্ত করার গ্যারান্টিযুক্ত । লিখিত হিসাবে কী-মানযুক্ত জোড়গুলি বাম থেকে ডানে sertedোকানো হয় , কারণ ভাষা নির্দিষ্ট গ্যারান্টি দেয় যে : যদি কী / ড্যাটুম জোড়গুলির একটি কমা-বিচ্ছিন্ন অনুক্রম দেওয়া হয় তবে অভিধানের এন্ট্রিগুলি সংজ্ঞায়িত করতে সেগুলি বাম থেকে ডানে মূল্যায়ন করা হয়dict()ডকুমেন্টেশন এমনকি একটি উদাহরণ রয়েছে।
মার্টিজন পিটারস

175
from collections import OrderedDict
OrderedDict((word, True) for word in words)

রয়েছে

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

মানগুলি True(বা অন্য কোনও অপরিবর্তনীয় বস্তু) হলে, আপনি এটি ব্যবহার করতে পারেন:

OrderedDict.fromkeys(words, True)

2
অবশ্যই লক্ষণীয় যে 'অপরিবর্তনীয়' অংশটি পাইথন প্রয়োগ করবে এমন কঠোর এবং দ্রুত নিয়ম নয় - এটির "একমাত্র" একটি ভাল ধারণা।
lvc

11
সচেতন থাকুন যে সমাধানগুলি যেমন: OrderedDict(FUTURE=[], TODAY=[], PAST=[])অযথা কাজ করবে না, যখন অ্যাপ্রোচ উল্লেখ করা OrderedDict([('FUTURE', []), ('TODAY', []), ('PAST', [])])হবে : ক্রমটি রাখবে।
andilabs

2
@ কান্দি আমি আর একটি সমস্যা পেয়েছি, যখন জসোনাইফ ব্যবহার করার সময়, অর্সনডিক্ট মনে হয় জসন ডেটা তৈরি করার সময় এটির অর্ডারটি নষ্ট হয়ে গেছে nyএভাবেই কি সমাধান করার জন্য?
tyan

github.com/pallet/flask/issues/974 এটি সমস্যার সমাধান করতে ব্যবহার করা যেতে পারে ..
tyan

5
পাইথন 3.7 এখন ডিফল্টরূপে আদেশ দিয়েছে dict mail.python.org/pipermail/python-dev/2017-
sertsedat

167

তাত্ত্বিক অংশটি ব্যাখ্যা করার পরিবর্তে আমি একটি সাধারণ উদাহরণ দেব।

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}

16
ডিক্ট টাইপের মতো অর্ডারডটিক্টকে ভর করার উপায় আছে কি?
tyan

2
OrderedDictপ্রকৃতপক্ষে সমস্যাটি সমাধান করে, তবে ... এই বিশেষ উদাহরণে আপনি একটি সাধারণ অভিধান ব্যবহার করে ঠিক একই ফলাফলটি পান
টোকনহাস

2
@ টনকনহাস: আমি কেবল একটি আদর্শ অভিধান দিয়ে উদাহরণটি চেষ্টা করেছি এবং পেয়েছি {'aol': 1, 'foo': 3}তাই আমি মনে করি এটি একটি ভাল উদাহরণস্বরূপ উদাহরণ।
twasbrillig

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

1
@tyan আপনি কল করতে পারেন OrderedDict.update()একটি iterable ধারণকারী কী-মান জোড়া সঙ্গে d1.upate([(key1, val1), (key2, val2)])
রুড আলথুইজেন

37

দ্রষ্টব্য যে এই উত্তরটি পাইথন3.7 এর পূর্বে পাইথন সংস্করণগুলিতে প্রযোজ্য। সিপিথন 3.6 বাস্তবায়ন বিশদ হিসাবে সর্বাধিক পরিস্থিতিতে সন্নিবেশ ক্রম বজায় রাখে। পাইথন .7..7 থেকে শুরু করে, এটি ঘোষণা করা হয়েছে যে বাস্তবায়নগুলি অবশ্যই সন্নিবেশের আদেশকে মেনে চলতে হবে।


পাইথন অভিধানগুলি নিরবচ্ছিন্ন are যদি আপনি আদেশিত অভিধান চান তবে সংগ্রহগুলি চেষ্টা করুন r আরআরআর্টডিক্ট

নোট করুন যে অর্ডারডিক্টটি পাইথন ২.7-এ স্ট্যান্ডার্ড লাইব্রেরিতে প্রবর্তিত হয়েছিল। অজগরটির যদি আপনার পুরানো সংস্করণ থাকে তবে আপনি অ্যাক্টিভস্টেটে অর্ডার করা অভিধানের রেসিপিগুলি পেতে পারেন ।


উপরে @ মার্টিজন এর পোস্ট দেখুন। অজগর 3.6 থেকে, ডোক সন্নিবেশ ক্রম সমর্থন করে।
tpk

13

শব্দকোষগুলি এমন একটি আদেশ ব্যবহার করবে যা অনুসন্ধানকে দক্ষ করে তোলে এবং আপনি এটি পরিবর্তন করতে পারবেন না,

আপনি কেবলমাত্র অবজেক্টগুলির একটি তালিকা ব্যবহার করতে পারেন (একটি সাধারণ ক্ষেত্রে একটি 2 উপাদান টিপল, বা এমনকি একটি শ্রেণি), এবং আইটেমগুলি শেষ পর্যন্ত যুক্ত করতে পারেন। এরপরে আপনি এতে আইটেমগুলি খুঁজতে লিনিয়ার অনুসন্ধান ব্যবহার করতে পারেন।

বিকল্পভাবে আপনি অর্ডার বজায় রাখার অভিপ্রায়ে তৈরি করা একটি ভিন্ন ডেটা স্ট্রাকচার তৈরি বা ব্যবহার করতে পারেন।


অভিধানগুলি একটি অর্ডার ব্যবহার করবে যা অনুসন্ধানকে দক্ষ করে তোলে শেষ পর্যন্ত, কেউ এটিকে নির্দেশ করেছেন।
scharette

7

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

উদাহরণ:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_tuple: print(test_dict[key])

এটি একটি বাজে ভার্চুয়াল, তবে আমি সময়ের জন্য চেপে গেছি এবং এটিই আমার সামনে এসে পৌঁছেছে ar

দ্রষ্টব্য: তালিকাগুলির তালিকার সাথে যোগাযোগ করা যে প্রস্তাবিত অন্য কেউ আমার কাছে আসলেই তা বোঝায় না, কারণ তালিকাগুলি অর্ডার করা হয় এবং তালিকাবদ্ধ হয় (এবং অভিধানগুলির চেয়ে আলাদা কাঠামোও))


দুর্দান্ত সমাধান। আমি এটি ফাইল করার জন্য জসন লিখতে ব্যবহার করব, সর্বদা একই ক্রমে।
হ্রভোজে টি

6

অভিধানের সাহায্যে আপনি যা করতে চান তা করতে পারবেন না। আপনি ইতিমধ্যে অভিধান d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}তৈরি করেছেন। আমি দেখেছি এটি ইতিমধ্যে তৈরি হয়ে গেলে শৃঙ্খলাবদ্ধ থাকার কোনও উপায় ছিল না। আমি যা করেছি তা হ'ল वस्तुটির পরিবর্তে একটি জসন ফাইল তৈরি করা হয়েছিল:

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

আমি ব্যবহার করতাম:

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

তারপরে ব্যবহৃত:

print json.dumps(r)

যাচাই করার জন্য.


1
তাহলে কেন একটি তালিকা থেকে অর্ডারডিক্ট দিয়ে শুরু করবেন না? জেএসওএন ফাইল এখানে সত্যই কিছু যুক্ত করে না।
মার্টিজন পিটারস

হ্যাঁ, তালিকাটি অর্ডার রাখতে আরও দরকারী তবে অভিধানগুলি অর্ডার করার বিষয়ে প্রশ্নের উত্তর ছিল। লোককে কোনও অভিধান ব্যবহারের সীমাবদ্ধতা সম্পর্কে কেবল অবহিত করা এবং যদি কোনও কারণে অভিধান ব্যবহার করার প্রয়োজন হয় তবে তাদের আশেপাশে একটি সম্ভাব্য কাজ প্রদান করা উচিত।
nevy3

1
কিন্তু যে অংশ ইতিমধ্যে অনেক পুরোনো উত্তর আওতায় পড়ে, 2012. ফিরে ডেটিং
Martijn Pieters

3
from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])

মূল সমস্যা যা এখন আর ডিক নয়, এটি টিপলগুলির একটি তালিকা
ওলেগ

2

আর একটি বিকল্প হ'ল পান্ডা ব্যবহার করা dataframeযেমন এটি আদেশের গ্যারান্টি দেয় এবং ডিকের মতো কাঠামোর আইটেমের সূচী অবস্থানগুলি।


1

সাধারণত, আপনি যদি একটি বর্গ ডিজাইন করতে পারে একটি অভিধান মত আচরণ, প্রধানত পদ্ধতি বাস্তবায়ন হতে __contains__, __getitem__, __delitem__, __setitem__এবং কিছু আরও অনেক কিছু। এই শ্রেণীর আপনার পছন্দমতো আচরণ থাকতে পারে, উদাহরণস্বরূপ কীগুলির উপর সাজানো পুনরুক্তিকারীকে গোপন করা ...


1

যদি আপনি একটি নির্দিষ্ট ক্রমে একটি অভিধান রাখতে চান তবে আপনি তালিকার একটি তালিকাও তৈরি করতে পারেন, যেখানে প্রথম আইটেমটি কী হবে এবং দ্বিতীয় আইটেমটির মান হবে এবং এই উদাহরণটির মতো দেখাবে

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3

7
এটি একটি "অভিধান" নয় কারণ আপনি পুরো সংগ্রহের অনুসন্ধান (O (n) সময় নিচ্ছেন) না করে তাদের কী দ্বারা আইটেমগুলি অনুসন্ধান করতে পারবেন না।
বিএইচএসপিটমনকি

1
হ্যাঁ, এটি কোনও অভিধান নয়, তবে পরিস্থিতির উপর নির্ভর করে এটি মূল পোস্টারের সমস্যাটির একটি বৈধ সমাধান দিতে পারে।
সানস্পার্ক

তিনি ঠিক কীভাবে আমরা চেয়েছিলেন তা বলেননি, কেবল এটিই অর্ডার করতে সক্ষম হতে চায় =), বরাবরের মতো একটি জিনিস করার প্রচুর উপায় রয়েছে।
pelos

1

জ্যাঙ্গো প্রকল্পটি বিকাশ করার সময় আমারও একই সমস্যা ছিল। আমি অর্ডারডিক্ট ব্যবহার করতে পারিনি, কারণ আমি পাইথনের একটি পুরাতন সংস্করণ চালাচ্ছিলাম, তাই সমাধানটি ছিল জাঙ্গোর সাউন্ডডিক্ট ক্লাসটি ব্যবহার করা:

https://code.djangoproject.com/wiki/SortedDict

যেমন,

from django.utils.datastructures import SortedDict
d2 = SortedDict()
d2['b'] = 1
d2['a'] = 2
d2['c'] = 3

দ্রষ্টব্য: এই উত্তরটি মূলত ২০১১ সালের collections.OrderedDict


0

আমি অভিধানের জন্য যা করেছি একই জিনিস করতে পারেন।

একটি তালিকা এবং খালি অভিধান তৈরি করুন:

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', 'hima@gmail.com']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.