दिलचस्प पोस्ट
उदाहरण के लिए बुरा व्यवहार माना जाता है? यदि हां, तो क्या परिस्थितियों में अभी भी बेहतर है? एसआईएम द्वारा MySQL ग्रुप एक अद्वितीय और नियतात्मक तरीके से, दो पूर्णांकियों को मैप करने के लिए सूची में एक गोली का रंग बदलने का एक आसान तरीका है? Cout के माध्यम से एक पूर्णांक के रूप में एक चरित्र को कैसे आउटपुट करना है? स्थैतिक चर initialisation आदेश Read () और fread () में क्या अंतर है? यूआरआई से पूर्ण फ़ाइल पथ कैसे प्राप्त करें iTextSharp एक पाद लेख पृष्ठ # के # एंड्रॉइड स्टूडियो डिबगर गलत रेखाएं रेखांकित करता है तैयार किए गए स्थान में सेटडेट का उपयोग करना क्यों नहीं पाया जाता है के लिए strchr एक int ले? पार्सलेल से परिवर्तनीय में संग्रहित कमान निष्पादित क्या इंटेलिएजे आईडीईए वेबस्टॉर्म और पीएचपीएसटॉम की सभी कार्यक्षमता प्लगइन्स के माध्यम से समाहित कर सकता है? दो अंकों (अक्षांश, देशांतर) के बीच की दूरी की गणना करना

एक शब्दकोश की प्रतिलिपि कैसे करें और केवल प्रतिलिपि संपादित करें

क्या कोई मुझसे इसकी व्याख्या करेगा? यह मेरे लिए कोई मतलब नहीं है

मैं एक शब्दकोश को दूसरे में कॉपी करता हूं और दूसरे को संपादित करता हूं और दोनों बदल जाते हैं ये क्यों हो रहा है?

>>> dict1 = {"key1": "value1", "key2": "value2"} >>> dict2 = dict1 >>> dict2 {'key2': 'value2', 'key1': 'value1'} >>> dict2["key2"] = "WHY?!" >>> dict1 {'key2': 'WHY?!', 'key1': 'value1'} 

वेब के समाधान से एकत्रित समाधान "एक शब्दकोश की प्रतिलिपि कैसे करें और केवल प्रतिलिपि संपादित करें"

अजगर कभी भी ऑब्जेक्ट कॉपी नहीं करता । जब आप dict2 = dict1 सेट करते हैं, तो आप उन्हें एक ही सटीक शब्द ऑब्जेक्ट को संदर्भित कर रहे हैं, इसलिए जब आप इसे उत्परिवर्तित करते हैं, तो इसके बारे में सभी संदर्भ ऑब्जेक्ट की वर्तमान स्थिति में रखते हुए रखते हैं

यदि आप डिक्ट की प्रतिलिपि बनाना चाहते हैं (जो कि दुर्लभ है), तो आपको इसे स्पष्ट रूप से करना होगा

 dict2 = dict(dict1) 

या

 dict2 = dict1.copy() 

जब आप dict2 = dict1 असाइन करते हैं, तो आप dict2 = dict1 प्रतिलिपि नहीं बना रहे हैं, इसका परिणाम dict2 में केवल dict1 लिए दूसरा नाम है

शब्दकोशों जैसे अस्थायी प्रकारों की copy deepcopy के लिए copy मॉड्यूल की copy / deepcopy का उपयोग करें।

 import copy dict2 = copy.deepcopy(dict1) 
 >>> x={'a': 1, 'b': {'m': 4, 'n': 5, 'o': 6}, 'c': 3} >>> u=x.copy() >>> v=dict(x) >>> import copy >>> w=copy.deepcopy(x) >>> x['a']=10 >>> x {'a': 10, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}} >>> u {'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}} >>> v {'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}} >>> w {'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}} >>> x['b']['m']=40 >>> x {'a': 10, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}} >>> u {'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}} >>> v {'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}} >>> w {'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}} 

आप केवल एक शब्दकोश शब्दकोश के साथ एक नया शब्दकोश बना सकते हैं। यह प्रतिलिपि आयात करने से बचा जाता है

 dout = dict((k,v) for k,v in mydict.items()) 

बिल्कुल अजगर में> = 2.7 आप कर सकते हैं:

 dout = {k:v for k,v in mydict.items()} 

लेकिन पीछे की तरफ के लिए, शीर्ष विधि बेहतर है।

आप नए कीवर्ड की प्रतिलिपि बना सकते हैं और अतिरिक्त कीवर्ड तर्कों के साथ dict को कॉल कर एक बार में संपादित कर सकते हैं:

 >>> dict1 = {"key1": "value1", "key2": "value2"} >>> dict2 = dict(dict1, key2="WHY?!") >>> dict1 {'key2': 'value2', 'key1': 'value1'} >>> dict2 {'key2': 'WHY?!', 'key1': 'value1'} 

पायथन में असाइनमेंट स्टेटमेंट ऑब्जेक्ट की प्रतिलिपि नहीं करते हैं, वे लक्ष्य और वस्तु के बीच बाइंडिंग बनाते हैं।

इसलिए, dict2 = dict1 , यह dict2 बीच एक और बाध्यकारी परिणाम और dict1 संदर्भ है।

यदि आप एक शब्दकोश की प्रतिलिपि बनाना चाहते हैं, तो आप copy module उपयोग कर सकते हैं। कॉपी मॉड्यूल में दो इंटरफ़ेस हैं:

 copy.copy(x) Return a shallow copy of x. copy.deepcopy(x) Return a deep copy of x. 

उथले और गहरी नकल के बीच का अंतर केवल यौगिक ऑब्जेक्ट्स (ऑब्जेक्ट जिसमें सूचियों या क्लास इंस्टेंसेस जैसे अन्य ऑब्जेक्ट होते हैं) के लिए ही प्रासंगिक है:

एक उथले प्रतिलिपि एक नए मिश्रित वस्तु का निर्माण करती है और फिर (यथासंभव) मूल में पाए जाने वाले वस्तुओं को संदर्भ सम्मिलित करता है।

एक गहरी प्रतिलिपि एक नए मिश्रित वस्तु का निर्माण करती है और फिर, पुनरावर्ती रूप से, मूल में मिली वस्तुओं की प्रतियां सम्मिलित करता है।

उदाहरण के लिए, अजगर 2.7.9 में:

 >>> import copy >>> a = [1,2,3,4,['a', 'b']] >>> b = a >>> c = copy.copy(a) >>> d = copy.deepcopy(a) >>> a.append(5) >>> a[4].append('c') 

और परिणाम है:

 >>> a [1, 2, 3, 4, ['a', 'b', 'c'], 5] >>> b [1, 2, 3, 4, ['a', 'b', 'c'], 5] >>> c [1, 2, 3, 4, ['a', 'b', 'c']] >>> d [1, 2, 3, 4, ['a', 'b']] 

अजगर 3.5+ पर ** अनपैकिंग ऑपरेटर का उपयोग करके इसे प्राप्त करने का एक आसान तरीका है। पेप 448 द्वारा निर्धारित

 >>>dict1 = {"key1": "value1", "key2": "value2"} >>>dict2 = {**dict1} >>>print(dict2) {'key1': 'value1', 'key2': 'value2'} >>>dict2["key2"] = "WHY?!" >>>print(dict1) {'key1': 'value1', 'key2': 'value2'} >>>print(dict2) {'key1': 'value1', 'key2': 'WHY?!'} 

** डिक्शनरी को एक नया शब्दकोश में अनपैक करें जिसमें डिक्ट 2 को सौंपा गया है।

हम यह भी पुष्टि कर सकते हैं कि प्रत्येक शब्दकोश में एक विशिष्ट आईडी है

 >>>id(dict1) 178192816 >>>id(dict2) 178192600 

dict2 = dict1 शब्दकोश की नकल नहीं करता है यह आपको एक ही शब्दकोश को संदर्भित करने के लिए प्रोग्रामर को दूसरा रास्ता ( dict2 ) देता है

अजगर में हर चर ( dict1 या str या __builtins__ जैसी सामग्री मशीन के अंदर कुछ छिपी हुई प्लेटोनिक "ऑब्जेक्ट" के लिए एक सूचक है

यदि आप dict1 = dict2 सेट dict1 = dict2 , तो आप एक ही ऑब्जेक्ट (या मेमोरी स्थान, या जो भी समानता आपको पसंद करते हैं) के लिए dict2 रूप में dict2 को dict2 अब, dict1 द्वारा संदर्भित ऑब्जेक्ट एक ही ऑब्जेक्ट dict2 द्वारा संदर्भित है

आप जांच सकते हैं: dict1 is dict2 True होना चाहिए इसके अलावा, id(dict1) के समान होना चाहिए।

आप चाहते हैं dict1 = copy(dict2) , या dict1 = deepcopy(dict2)

copy और deepcopy बीच का अंतर? deepcopy यह सुनिश्चित करेगा कि dict2 के तत्व (क्या आपने इसे सूची में इंगित किया?) भी प्रतियां हैं।

मैं deepcopy उपयोग नहीं करता हूं – आमतौर पर यह कोड लिखने के लिए खराब अभ्यास है जो इसकी आवश्यकता है (मेरी राय में)

यह भी मुझे भ्रमित, शुरू में, क्योंकि मैं एक सी पृष्ठभूमि से आ रहा था।

सी में, एक चर एक परिभाषित प्रकार के साथ स्मृति में एक स्थान है। वेरिएबल के मेमोरी स्थान में डेटा की एक चर प्रति असाइन करने के लिए।

लेकिन पायथन में, वेरिएबल्स ऑब्जेक्ट्स के समान पॉइंटर्स की तरह कार्य करते हैं। इसलिए एक चर को दूसरे में निर्दिष्ट करना एक प्रति नहीं बनाता है, यह केवल उसी ऑब्जेक्ट को चर नाम इंगित करता है।

dict1 एक प्रतीक है जो एक अंतर्निहित शब्दकोश वस्तु का संदर्भ देता है dict1 को dict1 को निर्दिष्ट करना केवल एक ही संदर्भ निर्दिष्ट करता है dict2 प्रतीक के माध्यम से चाबी का मूल्य बदलना अंतर्निहित वस्तु को बदलता है, जो भी dict1 प्रभावित करता है यह भ्रामक है।

संदर्भों की तुलना में अपरिवर्तनीय मूल्यों के बारे में तर्क करना कहीं आसान है, इसलिए जब भी संभव हो तो प्रतियां बनाएं:

 person = {'name': 'Mary', 'age': 25} one_year_later = {**person, 'age': 26} # does not mutate person dict 

यह वाक्यविन्यास के समान है:

 one_year_later = dict(person, age=26) 

जैसा कि अन्य लोगों ने समझाया है, अंतर्निहित dict क्या आप नहीं चाहते हैं लेकिन पायथन 2 में (और संभवत: 3 भी) आप आसानी से एक ValueDict वर्ग बना सकते हैं जो प्रतिलिपि बनाते हैं = ताकि आप यह सुनिश्चित कर सकें कि मूल बदल नहीं पाएगा।

 class ValueDict(dict): def __ilshift__(self, args): result = ValueDict(self) if isinstance(args, dict): dict.update(result, args) else: dict.__setitem__(result, *args) return result # Pythonic LVALUE modification def __irshift__(self, args): result = ValueDict(self) dict.__delitem__(result, args) return result # Pythonic LVALUE modification def __setitem__(self, k, v): raise AttributeError, \ "Use \"value_dict<<='%s', ...\" instead of \"d[%s] = ...\"" % (k,k) def __delitem__(self, k): raise AttributeError, \ "Use \"value_dict>>='%s'\" instead of \"del d[%s]" % (k,k) def update(self, d2): raise AttributeError, \ "Use \"value_dict<<=dict2\" instead of \"value_dict.update(dict2)\"" # test d = ValueDict() d <<='apples', 5 d <<='pears', 8 print "d =", d e = d e <<='bananas', 1 print "e =", e print "d =", d d >>='pears' print "d =", d d <<={'blueberries': 2, 'watermelons': 315} print "d =", d print "e =", e print "e['bananas'] =", e['bananas'] # result d = {'apples': 5, 'pears': 8} e = {'apples': 5, 'pears': 8, 'bananas': 1} d = {'apples': 5, 'pears': 8} d = {'apples': 5} d = {'watermelons': 315, 'blueberries': 2, 'apples': 5} e = {'apples': 5, 'pears': 8, 'bananas': 1} e['bananas'] = 1 # e[0]=3 # would give: # AttributeError: Use "value_dict<<='0', ..." instead of "d[0] = ..." 

कृपया यहां चर्चा की गई लावलू संशोधन पद्धति देखें: पायथन 2.7 – लावल्यू संशोधन के लिए शुद्ध वाक्यविन्यास । मुख्य अवलोकन यह है कि str और int पायथन में मूल्य के रूप में व्यवहार करते हैं (भले ही वे वास्तव में अस्थायी वस्तुओं हुड के नीचे हो) जब आप यह देख रहे हैं, तो कृपया यह भी ध्यान रखें कि str या int बारे में कुछ जादूई विशेष नहीं है। कई तरह के तरीकों में इस्तेमाल किया जा सकता है, और मैं कई मामलों के बारे में सोच सकता हूं जहां ValueDict समझ में आता है।

क्योंकि अजगर संदर्भ के साथ काम करता है, इसलिए जब आप dict2 = dict1 करते थे तो आप dict2 के संदर्भ को पास करते हैं, जो कि dict1 के समान था इसलिए, जब आप dict1 या dict2 में कोई परिवर्तन करते हैं, तो आप एक संदर्भ बदलते हैं, और दोनों दंडित chages। माफ करना, अगर मुझे अंग्रेजी में कुछ गलती है

क्योंकि, dict2 = dict1, dict2 dict1 के संदर्भ रखती है दोनों dict1 और dict2 स्मृति में एक ही स्थान के लिए अंक। अजगर में अस्थिर वस्तुओं के साथ काम करते समय यह सिर्फ एक सामान्य मामला है। जब आप अजगर में अस्थिर वस्तुओं के साथ काम कर रहे हैं तो आपको सावधान रहना चाहिए क्योंकि यह डीबग करना कठिन है। निम्न उदाहरण के रूप में

  my_users = { 'ids':[1,2], 'blocked_ids':[5,6,7] } ids = my_users.get('ids') ids.extend(my_users.get('blocked_ids')) #all_ids print ids#output:[1, 2, 5, 6, 7] print my_users #output:{'blocked_ids': [5, 6, 7], 'ids': [1, 2, 5, 6, 7]} 

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

आप सीधे उपयोग कर सकते हैं:

 dict2 = eval(repr(dict1)) 

जहां वस्तु dict2 dict1 की एक स्वतंत्र कॉपी है, ताकि आप dict1 को प्रभावित किए बिना dict2 को संशोधित कर सकें।

यह किसी भी प्रकार के ऑब्जेक्ट के लिए काम करता है