python - मैं मूल्य से एक शब्दकोश कैसे क्रमबद्ध करूं?




sorting dictionary (20)

मेरे पास डेटाबेस में दो फ़ील्ड से पढ़ने वाले मानों का एक शब्दकोश है: एक स्ट्रिंग फ़ील्ड और एक संख्यात्मक फ़ील्ड। स्ट्रिंग फ़ील्ड अद्वितीय है, इसलिए यह शब्दकोश की कुंजी है।

मैं चाबियाँ सॉर्ट कर सकता हूं, लेकिन मैं मूल्यों के आधार पर कैसे क्रमबद्ध कर सकता हूं?

नोट: मैंने स्टैक ओवरफ़्लो प्रश्न पढ़ा है मैं पायथन में शब्दकोश के मूल्यों से शब्दकोशों की सूची कैसे क्रमबद्ध करूं? और शायद मेरे कोड को शब्दकोशों की सूची रखने के लिए बदल सकता है, लेकिन चूंकि मुझे वास्तव में शब्दकोशों की एक सूची की आवश्यकता नहीं है, इसलिए मैं जानना चाहता हूं कि कोई आसान समाधान है या नहीं।

https://code.i-harness.com


पायथन 3.6 के रूप में अंतर्निहित निर्देश का आदेश दिया जाएगा

अच्छी खबर है, इसलिए मैपिंग जोड़े के ओपी का मूल उपयोग केस अद्वितीय स्ट्रिंग आईडी के साथ डेटाबेस से पुनर्प्राप्त किया गया है, जिसमें अंतर्निहित पायथन v3.6 + dict में मान के रूप में कुंजी और संख्यात्मक मान हैं, अब डालने के क्रम का सम्मान करना चाहिए।

यदि डेटाबेस क्वेरी से परिणामस्वरूप दो कॉलम तालिका अभिव्यक्तियां कहें:

SELECT a_key, a_value FROM a_table ORDER BY a_value;

दो पायथन tuples, k_seq और v_seq में संग्रहित किया जाएगा (संख्यात्मक सूचकांक द्वारा गठबंधन और पाठ्यक्रम की एक ही लंबाई के साथ), फिर:

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))

बाद में आउटपुट करने की अनुमति दें:

for k, v in ordered_map.items():
    print(k, v)

इस मामले में उपज (नए पायथन 3.6+ के लिए अंतर्निहित dict!):

foo 0
bar 1
baz 42

वी के प्रति मान एक ही क्रम में।

पाइथन 3.5 में जहां मेरी मशीन पर स्थापित होता है, वर्तमान में यह उपज करता है:

bar 1
foo 0
baz 42

विवरण:

जैसा कि 2012 में रेमंड हेटिंगर द्वारा प्रस्तावित किया गया था (विषय के साथ पाइथन-देव पर सीएफ मेल "तेजी से पुनरावृत्ति के साथ अधिक कॉम्पैक्ट शब्दकोश" ) और अब (2016 में) विक्टर स्टिनर द्वारा एक मेल में घोषणा की गई जिसमें पाइथन-डेव विषय के साथ "पायथन 3.6 dict बन गया कॉम्पैक्ट और एक निजी संस्करण प्राप्त होता है; और कीवर्ड " 27350 के फिक्स / कार्यान्वयन के कारण " आदेश दिया जाता है " पाइथन 3.6 में कॉम्पैक्ट और ऑर्डर किया गया" हम अब डालने के आदेश को बनाए रखने के लिए एक अंतर्निहित निर्देश का उपयोग करने में सक्षम होंगे !!

उम्मीद है कि इससे पहले चरण के रूप में ऑर्डर्ड डिक्ट कार्यान्वयन की पतली परत होगी। जैसा कि @ जिमफसारकिस-हिलियार्ड ने इंगित किया है, कुछ भविष्य में ऑर्डर्ड डिक्ट प्रकार के लिए भी उपयोग मामलों को देखते हैं। मुझे लगता है कि बड़े पैमाने पर पाइथन समुदाय सावधानी से निरीक्षण करेगा, अगर यह समय की परीक्षा खड़ा होगा, और अगले कदम क्या होंगे।

स्थिर कोडिंग द्वारा खोले गए संभावनाओं को याद न करने के लिए हमारी कोडिंग आदतों पर पुनर्विचार करने का समय:

  • कीवर्ड तर्क और
  • (मध्यवर्ती) dict भंडारण

पहला क्योंकि यह कुछ मामलों में कार्यों और विधियों के कार्यान्वयन में प्रेषण को आसान बनाता है।

दूसरी बात यह है कि यह पाइपलाइनों को संसाधित करने में मध्यवर्ती भंडारण के रूप में अधिक आसानी से उपयोग करने के लिए प्रोत्साहित करती है।

रेमंड हेटिंगर ने कृपया अपने सैन फ्रांसिस्को पायथन मीटुप ग्रुप प्रेजेंटेशन 2016-डीईसी -08 से " टेक टेक पाइथन 3.6 डिक्शनरी " के बारे में बताते हुए दस्तावेज प्रदान किया।

और शायद कुछ स्टैक ओवरफ्लो उच्च सजाए गए प्रश्न और उत्तर पृष्ठों को इस जानकारी के वेरिएंट प्राप्त होंगे और कई उच्च गुणवत्ता वाले उत्तरों के लिए प्रति संस्करण अपडेट की भी आवश्यकता होगी।

चेतावनी एम्प्टर (लेकिन नीचे 2017-12-15 अपडेट देखें):

जैसा कि @ajcr सही ढंग से नोट करता है: "इस नए कार्यान्वयन के आदेश-संरक्षण पहलू को कार्यान्वयन विवरण माना जाता है और इस पर भरोसा नहीं किया जाना चाहिए।" ( whatsnew36 से ) नाइट पिकिंग नहीं, लेकिन उद्धरण थोड़ा निराशाजनक कटौती की गई थी ;-)। यह जारी है "(यह भविष्य में बदल सकता है, लेकिन यह सभी मौजूदा और भविष्य के पायथन कार्यान्वयन के लिए क्रमशः अर्थशास्त्र को संरक्षित करने के लिए भाषा की कल्पना को बदलने से पहले कुछ रिलीज के लिए भाषा में इस नए dict कार्यान्वयन को वांछित करना चाहता है; यह भी भाषा के पुराने संस्करणों के साथ पिछड़ा-संगतता को संरक्षित रखने में मदद करता है जहां यादृच्छिक पुनरावृत्ति आदेश अभी भी प्रभावी है, उदाहरण के लिए पायथन 3.5)। "

इसलिए कुछ मानव भाषाओं (जैसे जर्मन) में, उपयोग भाषा को आकार देता है, और अब इच्छा घोषित कर दी गई है ... whatsnew36 में

2017-12-15 अपडेट करें:

पाइथन-देव सूची के लिए एक मेल में , गिडो वैन रॉसम ने घोषित किया:

इसे ऐसा बनाओ। "डिकट सम्मिलन आदेश रखता है" सत्तारूढ़ है। धन्यवाद!

तो, संस्करण प्रविष्टि आदेश का संस्करण 3.6 सीपीथन दुष्प्रभाव अब भाषा विशिष्टता का हिस्सा बन रहा है (और अब केवल एक कार्यान्वयन विस्तार नहीं)। उस मेल थ्रेड ने collections.OrderedDict लिए कुछ विशिष्ट डिजाइन लक्ष्यों को भी सामने लाया। ऑर्डर्ड डिक्टरी के दौरान रेमंड हेटिंगर द्वारा याद दिलाया गया।


जैसा कि सरल है: sorted(dict1, key=dict1.get)

खैर, वास्तव में "शब्द मानों द्वारा क्रमबद्ध" करना संभव है। हाल ही में मुझे कोड गोल्फ (स्टैक ओवरफ्लो प्रश्न कोड गोल्फ: वर्ड फ्रीक्वेंसी चार्ट ) में ऐसा करना पड़ा। घिरा हुआ, समस्या इस तरह की थी: एक पाठ दिया गया, गिनती है कि प्रत्येक शब्द का कितनी बार सामना होता है और आवृत्ति घटाने से क्रमबद्ध शीर्ष शब्दों की एक सूची प्रदर्शित करता है।

यदि आप कुंजी के रूप में शब्दों के साथ एक शब्दकोष बनाते हैं और प्रत्येक शब्द की घटनाओं की संख्या मूल्य के रूप में बनाते हैं, तो यहां सरलीकृत:

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
  d[w] += 1

तो आप sorted(d, key=d.get) साथ उपयोग की आवृत्ति द्वारा आदेशित शब्दों की एक सूची प्राप्त कर सकते हैं - सॉर्ट कुंजी की तरह शब्द घटनाओं की संख्या का उपयोग करके, sorted(d, key=d.get) पर पुनरावृत्ति करता है।

for w in sorted(d, key=d.get, reverse=True):
  print w, d[w]

मैं इस विस्तृत स्पष्टीकरण को लिख रहा हूं कि लोगों का क्या अर्थ है "मैं कुंजी से आसानी से सॉर्ट कर सकता हूं, लेकिन मैं मूल्य से कैसे क्रमबद्ध हूं" - और मुझे लगता है कि ओपी इस तरह के किसी मुद्दे को हल करने का प्रयास कर रहा था। और समाधान ऊपर दिखाए गए मानों के आधार पर कुंजी की सूची की तरह करना है।


आप इसका उपयोग कर सकते हैं:

sorted(d.items(), key=lambda x: x[1])

यह शब्दकोश के भीतर प्रत्येक प्रविष्टि के मानों से शब्दकोश को सबसे छोटे से सबसे बड़े तक सॉर्ट करेगा।


आप एक "उलटा इंडेक्स" भी बना सकते हैं

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

अब आपके व्यस्त मूल्य हैं; प्रत्येक मान में लागू कुंजी की एक सूची होती है।

for k in sorted(inverse):
    print k, inverse[k]

आप कस्टम फ़ंक्शन का भी उपयोग कर सकते हैं जिसे कुंजी पर पास किया जा सकता है।

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)

प्रयोगशाला कार्य का उपयोग करने का एक और तरीका है

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda t: t[1])

आप पाइथन के क्रमबद्ध फ़ंक्शन का उपयोग कर सकते हैं

sorted(iterable[, cmp[, key[, reverse]]])

इस प्रकार आप इसका उपयोग कर सकते हैं:

sorted(dictionary.items(),key = lambda x :x[1])

सॉर्ट किए गए फ़ंक्शन पर अधिक जानकारी के लिए इस लिंक पर https://docs.python.org/2/library/functions.html#sorted : https://docs.python.org/2/library/functions.html#sorted


एक शब्दकोश को सॉर्ट करना संभव नहीं है, केवल सॉर्ट किए गए शब्दकोश का प्रतिनिधित्व प्राप्त करना संभव है। शब्दकोश स्वाभाविक रूप से व्यवस्थित हैं, लेकिन सूचियों और tuples जैसे अन्य प्रकार, नहीं हैं। तो आपको सॉर्ट किए गए मानों का प्रतिनिधित्व करने के लिए एक आदेशित डेटा प्रकार की आवश्यकता है, जो एक सूची होगी-शायद टुपल्स की एक सूची होगी।

उदाहरण के लिए,

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x प्रत्येक tuple में दूसरे तत्व द्वारा क्रमबद्ध tuples की एक सूची होगी। dict(sorted_x) == x

और उन लोगों के लिए जो मूल्यों की बजाय कुंजी पर सॉर्ट करना चाहते हैं:

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

पायथन 3 में अनपॅकिंग की अनुमति नहीं है [1] हम इसका उपयोग कर सकते हैं

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_by_value = sorted(x.items(), key=lambda kv: kv[1])

डिक्ट्स को सॉर्ट नहीं किया जा सकता है, लेकिन आप उनमें से एक क्रमबद्ध सूची बना सकते हैं।

Dict मूल्यों की एक क्रमबद्ध सूची:

sorted(d.values())

मूल्य द्वारा क्रमबद्ध (कुंजी, मूल्य) जोड़े की एक सूची:

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))

दिया गया शब्दकोश

e = {1:39, 4:34, 7:110, 2:87}

छंटाई

sred = sorted(e.items(), key=lambda value: value[1])

परिणाम

[(4, 34), (1, 39), (2, 87), (7, 110)]

आप चीजों को मूल्य से क्रमबद्ध करने के लिए एक लैम्ब्डा फ़ंक्शन का उपयोग कर सकते हैं और उन्हें एक चर के अंदर संसाधित कर सकते हैं, इस मामले में मूल शब्दकोश के साथ sred

उम्मीद है की वो मदद करदे!


निम्नलिखित दृष्टिकोण आज़माएं। आइए निम्नलिखित डेटा के साथ मैडिक्ट नामक एक शब्दकोश को परिभाषित करें:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

यदि कोई कुंजी द्वारा कुंजी को सॉर्ट करना चाहता था, तो कोई ऐसा कुछ कर सकता था:

for key in sorted(mydict.iterkeys()):
    print "%s: %s" % (key, mydict[key])

यह निम्नलिखित आउटपुट वापस करना चाहिए:

alan: 2
bob: 1
carl: 40
danny: 3

दूसरी तरफ, यदि कोई मूल्य से एक शब्दकोश को सॉर्ट करना चाहता था (जैसा कि प्रश्न में पूछा गया है), तो कोई निम्न कार्य कर सकता है:

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

इस कमांड का परिणाम (मूल्य से शब्दकोश को सॉर्ट करना) निम्नलिखित को वापस करना चाहिए:

bob: 1
alan: 2
danny: 3
carl: 40

बेशक, याद रखें, आपको OrderedDict का उपयोग करने की आवश्यकता है क्योंकि नियमित पायथन शब्दकोश मूल क्रम नहीं रखते हैं।

from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key = lambda x: x[1]))

यदि आपके पास पाइथन 2.7 या उच्चतर नहीं है, तो आप जेनरेटर फ़ंक्शन में मानों पर सबसे अच्छा कर सकते हैं। (यहां 2.4 और 2.6 के लिए ऑर्डर्ड डिक्ट here , लेकिन

a) I don't know about how well it works 

तथा

b) You have to download and install it of course. If you do not have administrative access, then I'm afraid the option's out.)
def gen(originalDict):
    for x,y in sorted(zip(originalDict.keys(), originalDict.values()), key = lambda z: z[1]):
        yield (x, y)
    #Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want. 

for bleh, meh in gen(myDict):
    if bleh == "foo":
        print(myDict[bleh])

आप प्रत्येक मूल्य को भी प्रिंट कर सकते हैं

for bleh, meh in gen(myDict):
    print(bleh,meh)

यदि Python 3.0 या ऊपर का उपयोग नहीं करते हैं तो प्रिंट के बाद कोष्ठक को निकालना याद रखें


मुझे एक ही समस्या थी, और मैंने इसे इस तरह हल किया:

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

(जो लोग जवाब देते हैं, "एक नियम को हल करना संभव नहीं है" सवाल नहीं पढ़ा! असल में, "मैं चाबियाँ हल कर सकता हूं, लेकिन मैं मूल्यों के आधार पर कैसे क्रमबद्ध कर सकता हूं?" स्पष्ट रूप से इसका मतलब है कि वह एक सूची चाहता है चाबियाँ उनके मूल्यों के मूल्य के अनुसार क्रमबद्ध होती हैं।)

कृपया ध्यान दें कि ऑर्डर अच्छी तरह से परिभाषित नहीं है (उसी मान वाली कुंजी आउटपुट सूची में मनमाने ढंग से क्रम में होगी)।


यदि मान संख्यात्मक हैं तो आप संग्रह से काउंटर का भी उपयोग कर सकते हैं

from collections import Counter

x={'hello':1,'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]    

यह अक्सर नाम के उपयोग के लिए बहुत आसान हो सकता है। उदाहरण के लिए, आपके पास 'name' का एक शब्दकोश कुंजी के रूप में और 'स्कोर' मान के रूप में है और आप 'स्कोर' पर सॉर्ट करना चाहते हैं:

import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}

पहले सबसे कम स्कोर के साथ छंटनी:

worst = sorted(Player(v,k) for (k,v) in d.items())

पहले उच्चतम स्कोर के साथ छंटनी:

best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)

अब आप नाम और स्कोर प्राप्त कर सकते हैं, आइए दूसरे सबसे अच्छे खिलाड़ी (इंडेक्स = 1) को बहुत पागल रूप से इस तरह कहते हैं:

player = best[1]
player.name
    'Richard'
player.score
    7

यह शब्दकोश में कुंजी-मूल्य जोड़े की सूची देता है, जो मूल्य से उच्चतम से निम्नतम क्रमबद्ध होता है:

sorted(d.items(), key=lambda x: x[1], reverse=True)

कुंजी द्वारा क्रमबद्ध शब्दकोश के लिए, निम्न का उपयोग करें:

sorted(d.items(), reverse=True)

वापसी tuples की एक सूची है क्योंकि शब्दकोश खुद को हल नहीं किया जा सकता है।

यह दोनों मुद्रित या आगे गणना में भेजा जा सकता है।


हांक गे के जवाब के समान ही बहुत कुछ;

    sorted([(value,key) for (key,value) in mydict.items()])

या जॉन फौही द्वारा सुझाए गए अनुसार थोड़ा सा अनुकूलित किया गया;

    sorted((value,key) for (key,value) in mydict.items())


d.values() और d.keys() पर ज़िप का उपयोग करके एक समाधान यहां दिया गया है। इस लिंक के नीचे कुछ पंक्तियां (शब्दकोश दृश्य वस्तुओं पर) है:

यह ज़िप (): जोड़े = ज़िप (d.values ​​(), d.keys ()) का उपयोग कर (मान, कुंजी) जोड़े के निर्माण की अनुमति देता है।

तो हम निम्नलिखित कर सकते हैं:

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}

d_sorted = sorted(zip(d.values(), d.keys()))

print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]

Dicts से ValueSortedDict का उपयोग करें:

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 

[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

जैसा कि डिलेट्टन द्वारा इंगित किया गया है , पाइथन 3.6 अब आदेश जारी रखेगा ! मैंने सोचा कि मैं एक ऐसा फ़ंक्शन साझा करूंगा जो मैंने लिखा था जो एक पुनरावृत्त (टुपल, सूची, dict) की छंटाई को आसान बनाता है। बाद के मामले में, आप या तो कुंजी या मानों पर सॉर्ट कर सकते हैं, और यह खाते में संख्यात्मक तुलना ले सकता है। केवल> = 3.6 के लिए!

जब आप एक पुनरावर्तनीय पर क्रमबद्ध करने का प्रयास करते हैं, उदाहरण के साथ स्ट्रिंग्स और साथ ही इन्ट्स, सॉर्टेड () विफल हो जाएंगे। बेशक आप str () के साथ स्ट्रिंग तुलना को मजबूर कर सकते हैं। हालांकि, कुछ मामलों में आप वास्तविक संख्यात्मक तुलना करना चाहते हैं जहां 12से छोटा है 20(जो स्ट्रिंग तुलना में मामला नहीं है)। तो मैं निम्नलिखित के साथ आया था। जब आप स्पष्ट संख्यात्मक तुलना चाहते हैं तो आप ध्वज का उपयोग कर सकते हैं num_as_numजो सभी मानों को फ़्लोट में बदलने की कोशिश करके स्पष्ट संख्यात्मक सॉर्टिंग करने का प्रयास करेगा। यदि यह सफल होता है, तो यह संख्यात्मक सॉर्टिंग करेगा, अन्यथा यह स्ट्रिंग तुलना का सहारा लेगा।

सुधार या पुश अनुरोधों के लिए टिप्पणियां आपका स्वागत है।

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))

      return _sorted

    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    elif isinstance(iterable, tuple):
      sorted_list = tuple(_sort(None))
      return sorted_list
    elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")

यदि आपके मान पूर्णांक हैं, और आप पाइथन 2.7 या नए का उपयोग करते हैं, तो आप collections.Counterइसके बजाय उपयोग कर सकते हैं dictmost_commonविधि आप सभी आइटम, मूल्य के अनुसार क्रमबद्ध दे देंगे।





dictionary