मैं पायथन में खाली सूचियों के एक शब्दकोश को कैसे आरंभ करूं?


87

सूचियों का एक शब्दकोष बनाने का मेरा प्रयास मुझे व्यक्तिगत रूप से शब्दकोश कुंजियों की अनुमति देने में विफल रहा है। जब भी मैं सूचियों का शब्दकोश बनाता हूं और एक कुंजी को जोड़ने की कोशिश करता हूं, तो वे सभी अपडेट किए जाते हैं। यहाँ एक बहुत ही सरल परीक्षण मामला है:

data = {}
data = data.fromkeys(range(2),[])
data[1].append('hello')
print data

वास्तविक परिणाम: {0: ['hello'], 1: ['hello']}

अपेक्षित परिणाम: {0: [], 1: ['hello']}

यहाँ क्या काम करता है

data = {0:[],1:[]}
data[1].append('hello')
print data

वास्तविक और अपेक्षित परिणाम: {0: [], 1: ['hello']}

fromkeysविधि अपेक्षा के अनुसार काम क्यों नहीं कर रही है?

जवाबों:


110

एक बेकार परिणाम []देने के लिए दूसरे तर्क के रूप में पारित करना dict.fromkeys()- शब्दकोश में सभी मान समान सूची ऑब्जेक्ट होंगे।

पाइथन 2.7 या इसके बाद के संस्करण में, आप इसके बजाय एक डिक्टोनरी समझ का उपयोग कर सकते हैं:

data = {k: [] for k in range(2)}

पायथन के पुराने संस्करणों में, आप उपयोग कर सकते हैं

data = dict((k, []) for k in range(2))

3
वैसे यह एकतरफा व्यवहार नहीं है, किसी भी विचार का उपयोग सभी चाबियों के लिए क्यों किया जाता है?
बार

2
@Bar क्योंकि पायथन भाषा के शब्दार्थ के अलावा कुछ और कार्य नहीं किया जा सकता है। आप सभी कुंजियों के लिए मान के रूप में उपयोग की जाने वाली किसी एकल ऑब्जेक्ट में पास होते हैं, ताकि सभी कुंजियों के लिए एकल ऑब्जेक्ट का उपयोग किया जाए। इसके fromkeys()बजाय कारखाने के कार्य को स्वीकार करने की विधि के लिए बेहतर होगा , इसलिए हम listएक फ़ंक्शन के रूप में पारित कर सकते हैं , और प्रत्येक कुंजी के लिए एक बार फंकिटोन को बुलाया जाएगा, लेकिन यह वास्तविक एपीआई नहीं है dict.fromkeys()
स्वेन मार्नाच

3
यह बिल्कुल भी सहज नहीं है। मुझे ढूंढने में एक घंटा लग गया। धन्यवाद
Astrid

1
एक ही बात होती है अगर आप दूसरे तर्क के रूप में तानाशाही () पास करते हैं। बहुत ही चौंकाने वाला व्यवहार।
ओरली

@ इसके कारण यह है कि पहले एक खाली शब्दकोश बनाया गया है, और फिर इसके लिए एक संदर्भ सभी प्रारंभिकताओं को पारित किया गया है।
Dr_Zaszuś

82

इसके बजाय डिफ़ॉल्ट निर्णय का उपयोग करें :

from collections import defaultdict
data = defaultdict(list)
data[1].append('hello')

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

आपके उदाहरण में क्या हो रहा है कि आप एक (उत्परिवर्तित) सूची का उपयोग करते हैं :

alist = [1]
data = dict.fromkeys(range(2), alist)
alist.append(2)
print data

उत्पादन होगा {0: [1, 2], 1: [1, 2]}


2
मेरे मामले में, मुझे पहले से ही सभी कुंजियों को इनिशियलाइज़ करने की आवश्यकता है ताकि बाकी प्रोग्राम लॉजिक उम्मीद के मुताबिक काम कर सकें, लेकिन यह अन्यथा एक अच्छा समाधान होगा। धन्यवाद।
मार्टिन बर्च

मुझे लगता है कि इस उत्तर से क्या गायब है, यह कह रहा है कि यह समाधान काम करता है, जैसा कि ओपी के विपरीत है, क्योंकि listयहां एक खाली सूची नहीं है, लेकिन एक प्रकार (या आप इसे कॉल करने योग्य निर्माता के रूप में देख सकते हैं, मुझे लगता है)। इसलिए हर बार एक लापता कुंजी पारित होने के बाद, उसी की पुन: उपयोग करने के बजाय एक नई सूची बनाई जाती है।
Dr_Zaszuś

8

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

d = {k : v for k in blah blah blah}

शब्दकोश मूल्यों को शुरू करने पर शानदार सुझाव ... धन्यवाद कोबी! मैंने आपके उदाहरण को मौजूदा शब्दकोश में मूल्यों को रीसेट करने के लिए बढ़ाया, डी। मैंने इसे इस प्रकार प्रदर्शित किया: d = {k: 0 for k in d}
जॉन

vइस उत्तर में क्या है ?
Dr_Zaszuś

-2

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

data[:1] = ['hello']

2
यह कार्य क्यों करता है यह समझाने के लिए ओपी के लिए सहायक हो सकता है । मूल प्रश्न ने अक्स पोस्ट किया कि यह अपेक्षा के अनुरूप काम क्यों नहीं करता है।
william.taylor.09

@ william.taylor.09 यह थोड़े स्पष्ट है कि यह क्यों काम करता है, है न?
कोनर डेसन

ओपी है (पूछ रहा था) "क्यों गधों की विधि उम्मीद के मुताबिक काम नहीं कर रही है?"
william.taylor.09
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.