पायथन: कुंजी के रूप में ट्यूपल / शब्दकोष, चयन, सॉर्ट


104

मान लें कि मेरे पास विभिन्न रंगों के फल हैं, जैसे, 24 नीले केले, 12 हरे सेब, 0 नीले स्ट्रॉबेरी और इतने पर। मैं उन्हें पायथन में एक डेटा संरचना में व्यवस्थित करना चाहता हूं जो आसान चयन और छंटाई की अनुमति देता है। मेरा विचार उन्हें एक शब्दकोश में कुंजी के रूप में tuples के साथ डालने का था, जैसे,

{ ('banana',    'blue' ): 24,
  ('apple',     'green'): 12,
  ('strawberry','blue' ): 0,
  ...
}

या यहां तक ​​कि शब्दकोश, जैसे,

{ {'fruit': 'banana',    'color': 'blue' }: 24,
  {'fruit': 'apple',     'color': 'green'}: 12,
  {'fruit': 'strawberry','color': 'blue' }: 0,
  ...
}

मैं सभी नीले फलों की सूची, या सभी रंगों के केले, उदाहरण के लिए, या फल के नाम से इस शब्दकोश को क्रमबद्ध करना चाहता हूं। क्या इसे साफ तरीके से करने के तरीके हैं?

यह अच्छी तरह से हो सकता है कि ट्यूपल्स के साथ शब्दकोशों क्योंकि चाबियाँ इस स्थिति को संभालने का उचित तरीका नहीं हैं ।

सभी सुझावों का स्वागत है!


26
ऐसा लगता है कि आप एक डेटाबेस चाहते हैं ...
एडम रोसेनफील्ड

4
आप इस डेटा को मॉडल करने के लिए एक clasas को परिभाषित करने के लिए सबसे अच्छा होगा, बजाय इन मूल्यों के विभिन्न संग्रहों को समन्वित करने की कोशिश कर रहे हैं
Cuga

2
@AdamRosenfield शायद वह एक निर्माण कर रहा है।
प्रो। फल्केन

बस यह जोड़ना चाहता था कि कोई शब्दकोश उपलब्ध नहीं है, इसलिए दूसरा वाक्यविन्यास, जिसके बारे में पूछना संभव नहीं है क्योंकि {'फल': 'केला', 'रंग': 'ब्लू'} जो कि एक शब्दकोष है, जिसका उपयोग कुंजी के रूप में नहीं किया जा सकता है एक और शब्दकोश के लिए। यह एक TypeError का कारण होगा: अस्वाभाविक प्रकार: 'तानाशाह'।
epeleg

जवाबों:


147

व्यक्तिगत रूप से, मैं अजगर के बारे में प्यार करता हूँ चीजों में से एक तुगलकी तानाशाही संयोजन है। यहाँ आपके पास प्रभावी रूप से एक 2d सरणी है (जहाँ x = फलों का नाम और y = रंग), और मैं आम तौर पर 2d सरणियों को लागू करने के लिए टुपल्स के तानाशाह का समर्थक हूं, कम से कम जब कोई चीज जैसी numpyया डेटाबेस अधिक उपयुक्त नहीं होती है । इसलिए संक्षेप में, मुझे लगता है कि आपको एक अच्छा तरीका मिल गया है।

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

उस ने कहा, तुम भी नामांकित () पर विचार करना चाहिए । इस तरह से आप यह कर सकते हैं:

>>> from collections import namedtuple
>>> Fruit = namedtuple("Fruit", ["name", "color"])
>>> f = Fruit(name="banana", color="red")
>>> print f
Fruit(name='banana', color='red')
>>> f.name
'banana'
>>> f.color
'red'

अब आप अपने फ्रूटकाउंट का इस्तेमाल कर सकते हैं:

>>> fruitcount = {Fruit("banana", "red"):5}
>>> fruitcount[f]
5

अन्य चाल:

>>> fruits = fruitcount.keys()
>>> fruits.sort()
>>> print fruits
[Fruit(name='apple', color='green'), 
 Fruit(name='apple', color='red'), 
 Fruit(name='banana', color='blue'), 
 Fruit(name='strawberry', color='blue')]
>>> fruits.sort(key=lambda x:x.color)
>>> print fruits
[Fruit(name='banana', color='blue'), 
 Fruit(name='strawberry', color='blue'), 
 Fruit(name='apple', color='green'), 
 Fruit(name='apple', color='red')]

एक फल के सभी रंगों की सूची प्राप्त करने के लिए, चूलिग की गूंज, आपको कुंजियों को फ़िल्टर करना होगा, अर्थात

bananas = [fruit for fruit in fruits if fruit.name=='banana']

#senderle आपने एक अन्य उत्तर के लिए एक टिप्पणी के रूप में लिखा था "लेकिन मेरी आंत की भावना यह है कि एक डेटाबेस ओपी की जरूरतों के लिए ओवरकिल है;" इसलिए आप एक नामांकित उपवर्ग बनाना पसंद करते हैं। लेकिन वर्गों के उदाहरण क्या हैं यदि उनके डेटा को संसाधित करने के लिए अपने स्वयं के उपकरणों के साथ माइक्रो-डेटाबेस नहीं हैं?
22

क्या मैं उन उपनिवेशवादियों से निकाल सकता हूँ name='banana'?
निको श्लोमर

2
के रूप में chmullig ने कहा, आप चाबियाँ, यानी फिल्टर करने के लिए होता है bananas = filter(lambda fruit: fruit.name=='banana', fruits)या bananas = [fruit for fruit in fruits if fruit.name=='banana']। यह एक ऐसा तरीका है जिसमें नेस्टेड डाइक संभावित रूप से अधिक कुशल होते हैं; यह उन सभी तरीकों के बारे में है जो आप डेटा का उपयोग करने की योजना बनाते हैं।
प्रेषित

नामित टपल में अधिक कुंजी जोड़ने से चीजें आसान नहीं होंगी? मैं कहूंगा कि count
ओपनरीजल

18

आपका सबसे अच्छा विकल्प यह होगा कि आपके पास जो है उसके लिए एक सरल डेटा संरचना तैयार करें। फिर आप इन वस्तुओं को एक साधारण सूची में संग्रहीत कर सकते हैं और उन्हें अपनी इच्छानुसार किसी भी तरह से छांट / निकाल सकते हैं।

इस स्थिति के लिए, मैं निम्न वर्ग का उपयोग करूंगा:

class Fruit:
    def __init__(self, name, color, quantity): 
        self.name = name
        self.color = color
        self.quantity = quantity

    def __str__(self):
        return "Name: %s, Color: %s, Quantity: %s" % \
     (self.name, self.color, self.quantity)

फिर आप बस "फलों" उदाहरणों का निर्माण कर सकते हैं और उन्हें सूची में जोड़ सकते हैं, जैसा कि निम्नलिखित तरीके से दिखाया गया है:

fruit1 = Fruit("apple", "red", 12)
fruit2 = Fruit("pear", "green", 22)
fruit3 = Fruit("banana", "yellow", 32)
fruits = [fruit3, fruit2, fruit1] 

सरल सूची fruitsबहुत आसान, कम भ्रामक और बेहतर बनाए रखी जाएगी।

उपयोग के कुछ उदाहरण:

नीचे दिए गए कोड स्निपेट को चलाने के बाद सभी आउटपुट नीचे दिए गए हैं:

for fruit in fruits:
    print fruit

अनारक्षित सूची:

प्रदर्शित करता है:

Name: banana, Color: yellow, Quantity: 32
Name: pear, Color: green, Quantity: 22
Name: apple, Color: red, Quantity: 12

नाम से वर्णानुक्रम में क्रमबद्ध:

fruits.sort(key=lambda x: x.name.lower())

प्रदर्शित करता है:

Name: apple, Color: red, Quantity: 12
Name: banana, Color: yellow, Quantity: 32
Name: pear, Color: green, Quantity: 22

मात्रा द्वारा क्रमबद्ध:

fruits.sort(key=lambda x: x.quantity)

प्रदर्शित करता है:

Name: apple, Color: red, Quantity: 12
Name: pear, Color: green, Quantity: 22
Name: banana, Color: yellow, Quantity: 32

जहां रंग == लाल:

red_fruit = filter(lambda f: f.color == "red", fruits)

प्रदर्शित करता है:

Name: apple, Color: red, Quantity: 12

17

डेटाबेस, डिक्ट्स के प्रमुख, शब्दकोशों की सूची का शब्दकोश, टपल का नाम (यह एक उपवर्ग है), sqlite, अतिरेक ... मुझे अपनी आंखों पर विश्वास नहीं हुआ। और क्या ?

"यह अच्छी तरह से हो सकता है कि ट्यूपल्स के साथ शब्दकोशों के रूप में चाबियाँ इस स्थिति को संभालने का उचित तरीका नहीं हैं।"

"मेरी आंत महसूस कर रही है कि एक डेटाबेस ओपी की जरूरतों के लिए ओवरकिल है;"

हाँ! मैंने सोचा

इसलिए, मेरी राय में, टुपल्स की एक सूची काफी पर्याप्त है:

from operator import itemgetter

li = [  ('banana',     'blue'   , 24) ,
        ('apple',      'green'  , 12) ,
        ('strawberry', 'blue'   , 16 ) ,
        ('banana',     'yellow' , 13) ,
        ('apple',      'gold'   , 3 ) ,
        ('pear',       'yellow' , 10) ,
        ('strawberry', 'orange' , 27) ,
        ('apple',      'blue'   , 21) ,
        ('apple',      'silver' , 0 ) ,
        ('strawberry', 'green'  , 4 ) ,
        ('banana',     'brown'  , 14) ,
        ('strawberry', 'yellow' , 31) ,
        ('apple',      'pink'   , 9 ) ,
        ('strawberry', 'gold'   , 0 ) ,
        ('pear',       'gold'   , 66) ,
        ('apple',      'yellow' , 9 ) ,
        ('pear',       'brown'  , 5 ) ,
        ('strawberry', 'pink'   , 8 ) ,
        ('apple',      'purple' , 7 ) ,
        ('pear',       'blue'   , 51) ,
        ('chesnut',    'yellow',  0 )   ]


print set( u[1] for u in li ),': all potential colors'
print set( c for f,c,n in li if n!=0),': all effective colors'
print [ c for f,c,n in li if f=='banana' ],': all potential colors of bananas'
print [ c for f,c,n in li if f=='banana' and n!=0],': all effective colors of bananas'
print

print set( u[0] for u in li ),': all potential fruits'
print set( f for f,c,n in li if n!=0),': all effective fruits'
print [ f for f,c,n in li if c=='yellow' ],': all potential fruits being yellow'
print [ f for f,c,n in li if c=='yellow' and n!=0],': all effective fruits being yellow'
print

print len(set( u[1] for u in li )),': number of all potential colors'
print len(set(c for f,c,n in li if n!=0)),': number of all effective colors'
print len( [c for f,c,n in li if f=='strawberry']),': number of potential colors of strawberry'
print len( [c for f,c,n in li if f=='strawberry' and n!=0]),': number of effective colors of strawberry'
print

# sorting li by name of fruit
print sorted(li),'  sorted li by name of fruit'
print

# sorting li by number 
print sorted(li, key = itemgetter(2)),'  sorted li by number'
print

# sorting li first by name of color and secondly by name of fruit
print sorted(li, key = itemgetter(1,0)),'  sorted li first by name of color and secondly by name of fruit'
print

परिणाम

set(['blue', 'brown', 'gold', 'purple', 'yellow', 'pink', 'green', 'orange', 'silver']) : all potential colors
set(['blue', 'brown', 'gold', 'purple', 'yellow', 'pink', 'green', 'orange']) : all effective colors
['blue', 'yellow', 'brown'] : all potential colors of bananas
['blue', 'yellow', 'brown'] : all effective colors of bananas

set(['strawberry', 'chesnut', 'pear', 'banana', 'apple']) : all potential fruits
set(['strawberry', 'pear', 'banana', 'apple']) : all effective fruits
['banana', 'pear', 'strawberry', 'apple', 'chesnut'] : all potential fruits being yellow
['banana', 'pear', 'strawberry', 'apple'] : all effective fruits being yellow

9 : number of all potential colors
8 : number of all effective colors
6 : number of potential colors of strawberry
5 : number of effective colors of strawberry

[('apple', 'blue', 21), ('apple', 'gold', 3), ('apple', 'green', 12), ('apple', 'pink', 9), ('apple', 'purple', 7), ('apple', 'silver', 0), ('apple', 'yellow', 9), ('banana', 'blue', 24), ('banana', 'brown', 14), ('banana', 'yellow', 13), ('chesnut', 'yellow', 0), ('pear', 'blue', 51), ('pear', 'brown', 5), ('pear', 'gold', 66), ('pear', 'yellow', 10), ('strawberry', 'blue', 16), ('strawberry', 'gold', 0), ('strawberry', 'green', 4), ('strawberry', 'orange', 27), ('strawberry', 'pink', 8), ('strawberry', 'yellow', 31)]   sorted li by name of fruit

[('apple', 'silver', 0), ('strawberry', 'gold', 0), ('chesnut', 'yellow', 0), ('apple', 'gold', 3), ('strawberry', 'green', 4), ('pear', 'brown', 5), ('apple', 'purple', 7), ('strawberry', 'pink', 8), ('apple', 'pink', 9), ('apple', 'yellow', 9), ('pear', 'yellow', 10), ('apple', 'green', 12), ('banana', 'yellow', 13), ('banana', 'brown', 14), ('strawberry', 'blue', 16), ('apple', 'blue', 21), ('banana', 'blue', 24), ('strawberry', 'orange', 27), ('strawberry', 'yellow', 31), ('pear', 'blue', 51), ('pear', 'gold', 66)]   sorted li by number

[('apple', 'blue', 21), ('banana', 'blue', 24), ('pear', 'blue', 51), ('strawberry', 'blue', 16), ('banana', 'brown', 14), ('pear', 'brown', 5), ('apple', 'gold', 3), ('pear', 'gold', 66), ('strawberry', 'gold', 0), ('apple', 'green', 12), ('strawberry', 'green', 4), ('strawberry', 'orange', 27), ('apple', 'pink', 9), ('strawberry', 'pink', 8), ('apple', 'purple', 7), ('apple', 'silver', 0), ('apple', 'yellow', 9), ('banana', 'yellow', 13), ('chesnut', 'yellow', 0), ('pear', 'yellow', 10), ('strawberry', 'yellow', 31)]   sorted li first by name of color and secondly by name of fruit

1
नमस्ते, मुझे आपका समाधान पसंद है लेकिन यह ऑपरेशन जटिलता के मुद्दों को संबोधित नहीं करता है। सूची के आकार में सभी खोज प्रकार लाइनर (O (n)) हैं। यह भावना है कि ओपी कुछ कार्रवाई हो करना चाहते थे बनाना होगा, जबकि तेजी से तो दूसरों (उदाहरण के लिए हो रही है पीला केला गिनती कुछ है कि मैं हे में संभव होने की अपेक्षा करेंगे (1 होगा)।
epeleg

13

एक शब्दकोश शायद वह नहीं है जो आपको इस मामले में उपयोग करना चाहिए। अधिक पूर्ण विशेषताओं वाली लाइब्रेरी बेहतर विकल्प होगी। संभवतः एक वास्तविक डेटाबेस। सबसे आसान होगा sqlite । आप स्ट्रिंग में गुजरने के द्वारा पूरी बात को स्मृति में रख सकते हैं: 'स्मृति:' फ़ाइल नाम के बजाय।

यदि आप इस मार्ग को जारी रखना चाहते हैं, तो आप इसे कुंजी या मान में अतिरिक्त विशेषताओं के साथ कर सकते हैं। हालाँकि एक शब्दकोश दूसरे शब्दकोश की कुंजी नहीं हो सकता है, लेकिन टपल हो सकता है। डॉक्स समझाते हैं कि क्या स्वीकार्य है। यह एक अपरिवर्तनीय वस्तु होनी चाहिए, जिसमें स्ट्रिंग्स, संख्याएं और ट्यूपल शामिल हैं जिनमें केवल स्ट्रिंग्स और संख्याएं होती हैं (और अधिक ट्यूपल जिनमें केवल पुनरावर्ती प्रकार होते हैं ...)।

आप अपने पहले उदाहरण के साथ कर सकते हैं d = {('apple', 'red') : 4}, लेकिन जो आप चाहते हैं उसके लिए क्वेरी करना बहुत मुश्किल होगा। आपको ऐसा कुछ करने की आवश्यकता होगी:

#find all apples
apples = [d[key] for key in d.keys() if key[0] == 'apple']

#find all red items
red = [d[key] for key in d.keys() if key[1] == 'red']

#the red apple
redapples = d[('apple', 'red')]

4
मैंने नहीं किया, और नहीं, इस जवाब को नीचा दिखाऊंगा, क्योंकि बड़े पैमाने पर डेटाबेस (स्पष्ट रूप से!) सबसे अच्छा तरीका है। लेकिन मेरी आंत की भावना यह है कि एक डेटाबेस ओपी की जरूरतों के लिए ओवरकिल है; शायद यह है कि downvote बताते हैं?
20

4

ट्यूल के रूप में कुंजियों के साथ, आप बस दिए गए दूसरे घटक के साथ कुंजियों को फ़िल्टर करते हैं और इसे सॉर्ट करते हैं:

blue_fruit = sorted([k for k in data.keys() if k[1] == 'blue'])
for k in blue_fruit:
  print k[0], data[k] # prints 'banana 24', etc

छँटाई का काम करता है क्योंकि ट्यूपल्स में प्राकृतिक ऑर्डरिंग होती है अगर उनके घटकों में प्राकृतिक ऑर्डरिंग होती है।

कुंजी के रूप में बल्कि पूर्ण वस्तुओं के साथ, आप बस द्वारा फ़िल्टर करें k.color == 'blue'

आप वास्तव में कुंजियों को कुंजियों के रूप में उपयोग नहीं कर सकते हैं, लेकिन आप एक सरल वर्ग बना सकते हैं जैसे class Foo(object): passऔर मक्खी पर इसके लिए कोई विशेषता जोड़ सकते हैं:

k = Foo()
k.color = 'blue'

ये उदाहरण तानाशाही कुंजी के रूप में काम कर सकते हैं, लेकिन उनकी पारस्परिकता से सावधान रहें!


3

आपके पास एक शब्दकोश हो सकता है जहाँ प्रविष्टियाँ अन्य शब्दकोशों की सूची हैं:

fruit_dict = dict()
fruit_dict['banana'] = [{'yellow': 24}]
fruit_dict['apple'] = [{'red': 12}, {'green': 14}]
print fruit_dict

आउटपुट:

{[केला ’: [{'पीला’: २४}],: सेब ’: [{' लाल’: 12}, {} हरा ’: 14}]}

संपादित करें: जैसा कि eumiro ने बताया, आप शब्दकोशों के शब्दकोश का उपयोग कर सकते हैं:

fruit_dict = dict()
fruit_dict['banana'] = {'yellow': 24}
fruit_dict['apple'] = {'red': 12, 'green': 14}
print fruit_dict

आउटपुट:

{[केला ’: {'पीला’: २४},: सेब ’: {: हरा’: 14,' लाल ’: 12}}


2
शब्दकोशों की सूची का शब्दकोश? शायद शब्दकोश का शब्दकोश पर्याप्त होगा?
यूमिरो

@ यूमिरो: धन्यवाद, आप सही कह रहे हैं, और यह मेरा मूल विचार था। हालाँकि, मैंने इसे मूल उदाहरण को कोड करते हुए डिक्ट्स की सूचियों के एक बड़े हिस्से में बदल दिया। मैंने डिक्ट्स के उदाहरण का एक ताना-बाना जोड़ा है।
ग्रीनमैट

नेस्टेड शब्दकोश भ्रमित हो जाते हैं। कृपया मेरा उत्तर देखें
Cuga

@ चुगा: मैं मानता हूं कि डक्ट्स इत्यादि से भ्रमित हो सकते हैं। मैं केवल @ नीको के प्रश्न के उत्तर के लिए एक उदाहरण प्रदान कर रहा हूं।
ग्रीनमैट

मैं क्षमा चाहता हूँ: मेरा मतलब यह नहीं है कि आपका समाधान गलत है; यह स्पष्ट रूप से काम करता है और कुछ स्थितियों में यह आदर्श हो सकता है। मैं स्थिति पर अपना लेना साझा करना चाहता था।
21

2

इस प्रकार का डेटा कुशलता से एक Trie जैसी डेटा संरचना से खींचा जाता है। यह तेजी से छँटाई के लिए भी अनुमति देता है। स्मृति दक्षता हालांकि वह महान नहीं हो सकती है।

एक पारंपरिक तिकड़ी वृक्ष में एक शब्द के प्रत्येक अक्षर को नोड के रूप में संग्रहीत करती है। लेकिन आपके मामले में आपका "वर्णमाला" अलग है। आप पात्रों के बजाय तार संचय कर रहे हैं।

यह कुछ इस तरह लग सकता है:

root:                Root
                     /|\
                    / | \
                   /  |  \     
fruit:       Banana Apple Strawberry
              / |      |     \
             /  |      |      \
color:     Blue Yellow Green  Blue
            /   |       |       \
           /    |       |        \
end:      24   100      12        0

इस लिंक को देखें: अजगर में trie


2

आप दो कुंजी का स्वतंत्र रूप से उपयोग करना चाहते हैं, इसलिए आपके पास दो विकल्प हैं:

  1. के रूप में {'banana' : {'blue' : 4, ...}, .... }और दो dicts के साथ डेटा को स्टोर करें {'blue': {'banana':4, ...} ...}। फिर, खोज करना और छांटना आसान है, लेकिन आपको यह सुनिश्चित करना होगा कि आप एक साथ dicts को संशोधित करें।

  2. इसे सिर्फ एक तानाशाही के रूप में संग्रहीत करें, और फिर उन कार्यों को लिखें जो उन पर पुनरावृत्त करते हैं जैसे:

    d = {'banana' : {'blue' : 4, 'yellow':6}, 'apple':{'red':1} }
    
    blueFruit = [(fruit,d[fruit]['blue']) if d[fruit].has_key('blue') for fruit in d.keys()]

मैं यह पता नहीं लगा सकता कि मेरे उत्तर का कोड सही प्रारूप में क्यों नहीं दिखा। मैंने कोड के रूप में अंतिम दो पंक्तियों को संपादित और चिह्नित करने की कोशिश की है, लेकिन यह काम नहीं करता है!
21

1
आपने एक क्रमांकित सूची बनाई है, और पार्सर उस सूची के दूसरे आइटम की निरंतरता के रूप में कोड (इंडेंट 4 रिक्त स्थान) की व्याख्या कर रहा है। कोड को कुल 8 के लिए एक और 4 रिक्त स्थान का संकेत दें, और पार्सर कोड के रूप में कोड को पहचान लेगा और इसे सही ढंग से प्रारूपित करेगा।
प्रेषित
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.