2010-07-07 12 views
83

मैं अजगर के लिए नया हूं और मेरे पास प्रत्येक वर्ष के लिए वर्षों और मूल्यों की एक सूची है। मैं क्या करना चाहता हूं यह जांचना है कि क्या एक शब्दकोश में पहले से मौजूद है और यदि ऐसा होता है, तो विशिष्ट कुंजी के लिए मानों की उस सूची में मान संलग्न करें।पायथन शब्दकोश में एक कुंजी के लिए एकाधिक मान संलग्न करें

तो उदाहरण के लिए, मैं साल की एक सूची है और प्रत्येक वर्ष के लिए एक मान हो:

2010 
2 
2009 
4 
1989 
8 
2009 
7 

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

2010: 2 
2009: 4, 7 
1989: 8 

अभी मैं निम्नलिखित है:

d = dict() 
years = [] 

(get 2 column list of years and values) 

for line in list:  
    year = line[0] 
    value = line[1] 

for line in list: 
    if year in d.keys(): 
     d[value].append(value) 
    else: 
     d[value] = value 
     d[year] = year 
+1

एक और समान प्रश्न: http://stackoverflow.com/questions/5378231/python-list-to-dictionary-multiple-values-per-key – River

उत्तर

116

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

years_dict = dict() 

for line in list: 
    if line[0] in years_dict: 
     # append the new number to the existing array at this slot 
     years_dict[line[0]].append(line[1]) 
    else: 
     # create a new array in this slot 
     years_dict[line[0]] = [line[1]] 

क्या आप के साथ में years_dict एक शब्दकोश है कि ऐसा दिखाई देता है अंत करना चाहिए:

{ 
    "2010": [2], 
    "2009": [4,7], 
    "1989": [8] 
} 

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

+14

यह निश्चित रूप से ऐसा करने का सही तरीका है, हालांकि सबसे ज़रूरी नहीं है संक्षिप्त पायथन इंस्टॉलेशन के लिए उपलब्ध डिफ़ॉल्ट टूलसेट के हिस्से के रूप में 'dict.setdefault()' और 'collections.defaultdict' जैसी शानदार चाल की उपलब्धता को संक्षिप्त किया गया। – jathanism

+2

धन्यवाद, यह वही था जो मुझे अपनी समस्या को ठीक करने के लिए आवश्यक था – anon

+0

यदि आप डिफॉल्टडिक्ट का उपयोग करते हैं तो इसे एक सूची के रूप में सेट करें: dd = defaultdict (list) – sparrow

67

आप collections.defaultdict (पायथन 2.5 में जोड़े गए) का उपयोग करके सबसे अच्छा होगा। यह आपको एक अनुपलब्ध कुंजी के डिफ़ॉल्ट ऑब्जेक्ट प्रकार (जैसे list) निर्दिष्ट करने की अनुमति देता है।

बजाय का एक प्रमुख बनाने अगर यह पहले अस्तित्व में नहीं है और फिर कुंजी के मूल्य के जोड़कर, आप मध्यम आदमी काट और बस सीधे गैर मौजूदा कुंजी को संलग्न वांछित परिणाम प्राप्त करने के लिए।

एक त्वरित उदाहरण अपने डेटा का उपयोग:

>>> from collections import defaultdict 
>>> data = [(2010, 2), (2009, 4), (1989, 8), (2009, 7)] 
>>> d = defaultdict(list) 
>>> d 
defaultdict(<type 'list'>, {}) 
>>> for year, month in data: 
...  d[year].append(month) 
... 
>>> d 
defaultdict(<type 'list'>, {2009: [4, 7], 2010: [2], 1989: [8]}) 

इस तरह से आप के बारे में आप एक साल या नहीं के साथ जुड़े एक अंकों देखा है या नहीं में चिंता करने की जरूरत नहीं है। आप बस संलग्न और भूल जाते हैं, यह जानकर कि एक लापता कुंजी हमेशा एक सूची होगी। यदि कोई कुंजी पहले से मौजूद है, तो इसे अभी जोड़ा जाएगा।

25

आप setdefault का उपयोग कर सकते हैं।

for line in list: 
    d.setdefault(year, []).append(value) 

यह काम करता है क्योंकि SetDefault शब्दकोश पर यह स्थापित करने के रूप में सूची लौटाती है और साथ ही, और क्योंकि एक सूची परिवर्तनशील है, संस्करण SetDefault द्वारा वापस करने के लिए जोड़कर शब्दकोश के अंदर ही संस्करण के लिए यह जोड़कर रूप में ही है । यदि इसका कोई मतलब निकले तो।

12
d = {} 

# import list of year,value pairs 

for year,value in mylist: 
    try: 
     d[year].append(value) 
    except KeyError: 
     d[year] = [value] 

पायथन रास्ता - अनुमति मांगने से क्षमा करना आसान है!

+6

पायथन तरीका कार्यक्षमता डुप्लिकेट नहीं करना है – SilentGhost

+1

मुझे नहीं पता कि यहां डुप्लिकेशंस कैसा है। –

2

यदि आप इन मानों को tuples की सूची में प्राप्त करते हैं तो यह आसान है। ऐसा करने के लिए, आप सूची स्लाइसिंग और ज़िप फ़ंक्शन का उपयोग कर सकते हैं।

data_in = [2010,2,2009,4,1989,8,2009,7] 
data_pairs = zip(data_in[::2],data_in[1::2]) 

पिन data_in की भी और अजीब प्रविष्टियों इस मामले में, सूची के एक मनमाना संख्या लेता है, और उन्हें एक साथ डालता है एक टपल में।

अब हम setdefault विधि का उपयोग कर सकते हैं।

data_dict = {} 
for x in data_pairs: 
    data_dict.setdefault(x[0],[]).append(x[1]) 

setdefault एक प्रमुख और एक डिफ़ॉल्ट मान लेता है, और या तो जुड़े मान देता है, या अगर कोई वर्तमान मान, डिफ़ॉल्ट मान है। इस मामले में, हम या तो खाली या आबादी वाली सूची प्राप्त करेंगे, जिसे हम वर्तमान मूल्य जोड़ते हैं।

# define an empty dict 
years_dict = dict() 

for line in list: 
    # here define what key is, for example, 
    key = line[0] 
    # check if key is already present in dict 
    if key not in years_dict: 
     years_dict[key] = [] 
    # append some value 
    years_dict[key].append(some.value) 
4

यहाँ not in ऑपरेटर का उपयोग ऐसा करने का एक वैकल्पिक तरीका है "एक कॉल में जांचें कि क्या कुंजी पहले से मौजूद है और यदि कोई नई सूची नहीं है" की जांच करें। यह आपको जनरेटर अभिव्यक्ति लिखने की अनुमति देता है जिसे deque द्वारा कुशलतापूर्वक जितना संभव हो सके कतार की लंबाई शून्य पर सेट की जाती है। डेक तुरंत खारिज कर दिया जाएगा और परिणाम d में होगा।

यह कुछ ऐसा है जो मैंने अभी मजाक के लिए किया था। मैं इसका इस्तेमाल करने की सिफारिश नहीं करता हूं। एक डेक के माध्यम से मनमाने ढंग से पुनरावृत्तियों का उपभोग करने के लिए एक समय और एक जगह है, और यह निश्चित रूप से यह नहीं है।

1

आप एक (लगभग) एक लाइनर चाहते हैं:

 
from collections import deque 

d = {} 
deque((d.setdefault(year, []).append(value) for year, value in source_of_data), maxlen=0) 

dict.detdefault उपयोग करके, आप विचार कर सकते हैं संपुटित

+0

यदि मैं 'डेटा = [(2010, 2), (200 9, 4), (1 9 8 9, 8), (200 9, 7)] का उपयोग करता हूं, तो यह' डेक ([]) 'देता है। – Cleb

+0

@ क्लेब। परिणाम 'डी' में है। डेक को त्याग दिया जाना चाहिए। यह केवल कार्य है जनरेटर को जितनी जल्दी हो सके संसाधित करना है। –

+0

ओउप्स, बेवकूफ मुझे; तो यह वास्तव में काफी अच्छी तरह से काम करता है ... – Cleb

संबंधित मुद्दे