ශබ්ද කෝෂයක් පිටපත් කරන්නේ කෙසේද සහ පිටපත පමණක් සංස්කරණය කරන්න


909

කරුණාකර යමෙකුට මෙය මට පැහැදිලි කළ හැකිද? මෙය මට කිසිම තේරුමක් නැත.

මම ශබ්ද කෝෂයක් වෙනත් තැනකට පිටපත් කර දෙවැන්න සංස්කරණය කර දෙකම වෙනස් කරමි. මෙය සිදුවන්නේ ඇයි?

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

4
පයිතන් යොමුව දෘශ්‍යමාන කිරීම සඳහා පයිතන් ටියුටර් විශිෂ්ටයි. මෙන්න මෙම කේතය අවසාන පියවරේදී . ඔබට බලන්න පුළුවන් dict1සහ dict2එම dict කිරීමට අදහස්.
wjandrea

Answers:


931

පයිතන් කිසි විටෙකත් වස්තූන් ව්‍යංගයෙන් පිටපත් නොකරයි . ඔබ සැකසූ විට dict2 = dict1, ඔබ ඒවා එකම නිශ්චිත වස්තුවකට යොමු කිරීමට සලස්වයි, එබැවින් ඔබ එය විකෘති කරන විට, ඒ පිළිබඳ සියලු යොමු කිරීම් වස්තුව එහි වත්මන් තත්වයට යොමු කරයි.

ඔබට ආ ict ාව පිටපත් කිරීමට අවශ්‍ය නම් (එය දුර්ලභ ය), ඔබ එය පැහැදිලිවම කළ යුතුය

dict2 = dict(dict1)

හෝ

dict2 = dict1.copy()

27
“Dict2 සහ dict1 එකම ශබ්ද කෝෂයට යොමු කරන්න” යැයි පැවසීම වඩා හොඳ විය හැකිය , ඔබ වෙනස් කරන්නේ dict1 හෝ dict2 නොව ඔවුන් පෙන්වා දෙන දෙයයි.
ග්‍රේවිසාර්ක්ස්

288
Dict.copy () නොගැඹුරු බව සලකන්න, කැදැලි ලැයිස්තුවක් තිබේ නම් / යනාදිය එහි වෙනස්කම් දෙකටම අදාළ වේ. IIRC. ඩීප්කොපි මගින් එය වළක්වනු ඇත.
විල්

16
පයිතන් කිසි විටෙකත් ව්‍යංගයෙන් වස්තූන් පිටපත් නොකරන බව නිවැරදි නැත. Int, float, and bool වැනි ප්‍රාථමික දත්ත වර්ග ද වස්තු ලෙස සලකනු ලැබේ (එය dir(1)බැලීමට පමණක් කරන්න ), නමුත් ඒවා ව්‍යංගයෙන් පිටපත් කරනු ලැබේ.
ඩැනියෙල් කුල්මන්

18
an ඩැනියෙල්කුල්මන්, මම සිතන්නේ ඔබ වැඩ කරන වෙනත් භාෂා සමඟ පදනම්ව පයිතන් පිළිබඳ වරදවා වටහාගැනීම් ඇති විය හැකි බවයි. පයිතන්හි, අ) "ප්‍රාථමික දත්ත වර්ග" පිළිබඳ සංකල්පයක් නොමැත. int,, floatසහ boolනිදසුන් සැබෑ පයිතන් වස්තූන් වන අතර, ආ) මෙම වර්ගවල වස්තූන් ඔබ ඒවා පසු කරන විට ව්‍යංගයෙන් පිටපත් නොකෙරේ, අර්ථකථන පයිතන් මට්ටමින් නොව නිශ්චිතවම CPython හි ක්‍රියාත්මක කිරීමේ විස්තරයක් ලෙස නොවේ.
මයික් ග්‍රැහැම්

50
“ගැඹුරු පිටපත හානිකර යැයි සැලකේ” වැනි සනාථ නොකළ වාචාල කතා උදව්වක් නොවේ. අනෙක් සියල්ලම සමාන වන අතර, නොගැඹුරු පිටපත් කිරීම සංකීර්ණ දත්ත ව්‍යුහයක් එකම ව්‍යුහයක් ගැඹුරින් පිටපත් කිරීමට වඩා අනපේක්ෂිත අද්දර ගැටළු ඇති කිරීමට සැලකිය යුතු ලෙස වැඩි ය. මුල් වස්තුව වෙනස් කරන පිටපතක් පිටපතක් නොවේ; එය දෝෂයකි. Ergo, බොහෝ භාවිතය නඩු පරම යුතු කතා copy.deepcopy()කරනවාට වඩා dict()හෝ dict.copy(). ඉම්රාන් ගේ සංක්ෂිප්ත පිළිතුරක් මෙම පිළිතුර මෙන් නොව, සිහි විකල් දකුණු පැත්තෙන් වේ.
සිසිල් කරි

693

ඔබ පවරන විට dict2 = dict1, ඔබ එහි පිටපතක් සාදන්නේ නැත dict1, එහි ප්‍රති results ලය වන්නේ dict2වෙනත් නමක් පමණි dict1.

ශබ්ද කෝෂ, භාවිතා වැනි mutable වර්ග පිටපත් කිරීමට copy/ deepcopycopyමොඩියුලය.

import copy

dict2 = copy.deepcopy(dict1)

86
මා සමඟ වැඩ කරන ඕනෑම ශබ්ද කෝෂයක් සඳහා, ගැඹුරු පිටපත යනු මට අවශ්‍ය දෙයයි ... දෝෂයක් හේතුවෙන් මට පැය කිහිපයක් අහිමි විය, එයට හේතුව මට කැදැලි ශබ්දකෝෂයක සම්පූර්ණ පිටපතක් නොලැබීම සහ කැදැලි ඇතුළත් කිරීම්වල මගේ වෙනස්වීම් මුල් පිටපතට බලපාන බැවිනි. .
flutefreak7

7
මෙහෙත් එහෙමයි. deepcopy () උපක්‍රමය කරයි. මුල් සිදුවීමේ 'පිටපතකට' කාලරාමුව එක් කිරීමෙන් භ්‍රමණය වන හැඹිලියක් තුළ මගේ කැදැලි නියෝග අවුල් කරමින් සිටියේය. ඔබට ස්තුතියි!
fxstein

8
මෙය ඇත්ත වශයෙන්ම නිවැරදි පිළිතුර ලෙස සලකුණු කළ යුතුය; මෙම පිළිතුර සාමාන්‍ය වන අතර එය ශබ්දකෝෂ ශබ්ද කෝෂයක් සඳහාද ක්‍රියා කරයි.
orezvani

32
මෙය පිළිගත් පිළිතුර විය යුතුය. දැනට පිළිගත් පිළිතුරේ විවරණ කොටසේ ඇතුළත් කර ඇති සනාථ නොකළ “ගැඹුරු පිටපත හානිකර යැයි සැලකේ” වාචාල කතා, කැදැලි ශබ්ද කෝෂ පිටපත් කිරීමේදී (මෙහි ලේඛනගත කර ඇති ඒවා වැනි) සමමුහුර්ත කිරීමේ දුක් කරදර වලට නිර්දය ලෙස ආරාධනා කරයි.
සිසිල් කරි

deepcopy යනු සංකීර්ණ ශබ්ද කෝෂ ව්‍යුහයකදී යා යුතු මාර්ගයයි. dict1.copy () හුදෙක් යතුරු වල අගයන් යොමු කරන්නේ වස්තු ලෙස නොව යොමු ලෙස ය.
රෝහිත් එන්

202

අතර dict.copy()හා dict(dict1)පිටපතක් ජනනය, ඔවුන් පමණක් නොගැඹුරු පිටපත්. ඔබට ගැඹුරු පිටපතක් copy.deepcopy(dict1)අවශ්‍ය නම් අවශ්‍ය වේ. උදාහරණයක්:

>>> source = {'a': 1, 'b': {'m': 4, 'n': 5, 'o': 6}, 'c': 3}
>>> copy1 = x.copy()
>>> copy2 = dict(x)
>>> import copy
>>> copy3 = copy.deepcopy(x)
>>> source['a'] = 10  # a change to first-level properties won't affect copies
>>> source
{'a': 10, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy3
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> source['b']['m'] = 40  # a change to deep properties WILL affect shallow copies 'b.m' property
>>> source
{'a': 10, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy3  # Deep copy's 'b.m' property is unaffected
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}

පයිතන් copyමොඩියුලයේ ලියකියවිලි වලින් නොගැඹුරු එදිරිව ගැඹුරු පිටපත් සම්බන්ධයෙන් :

නොගැඹුරු සහ ගැඹුරු පිටපත් කිරීම අතර වෙනස අදාළ වන්නේ සංයුක්ත වස්තු සඳහා පමණි (ලැයිස්තු හෝ පන්ති අවස්ථා වැනි වෙනත් වස්තු අඩංගු වස්තු):

  • නොගැඹුරු පිටපතක් නව සංයුක්ත වස්තුවක් සාදන අතර (හැකි තාක් දුරට) මුල් පිටපතෙහි ඇති වස්තූන් වෙත එය යොමු කරයි.
  • ගැඹුරු පිටපතක් නව සංයුක්ත වස්තුවක් සාදන අතර, නැවත නැවත, මුල් පිටපතෙහි ඇති වස්තූන්ගේ පිටපත් එයට ඇතුල් කරයි.

2
මෙය නිවැරදි පිළිතුර විය යුතු අතර එය පැහැදිලිවම ආ ict ාව ඉක්මවා නොයන අතර වෙනත් ප්‍රාථමික ව්‍යුහයන් සඳහා භාවිතා කළ හැකිය.
නිකොලාස්ග්

28
පැහැදිලි කිරීම සඳහා: w=copy.deepcopy(x)ප්‍රධාන රේඛාව වේ.
මත්පැන්

dict2 = dict1සහ අතර ඇති වෙනස dict2 = copy.deepcopy(dict1)කුමක්ද?
TheTank

1
TTheTank, y = x නම් දෙක (යොමු) එකම වස්තුවකට යොමු කරයි, එනම් "y යනු x" සත්‍ය වේ. X හරහා වස්තුව මත සිදුකරන ඕනෑම වෙනසක් y හරහා එකම වෙනසකට සමාන වේ. කෙසේ වෙතත්, u, v, w යනු ක්ෂණිකකරණයේදී x වෙතින් පිටපත් කළ අගයන් ඇති නව වෙනස් වස්තූන් සඳහා යොමු කිරීම් වේ. U, v (නොගැඹුරු පිටපත) සහ w (ගැඹුරු පිටපත) අතර ඇති වෙනස්කම් සඳහා කරුණාකර docs.python.org/2/library/copy.html
gpanda

66

පයිතන් 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

ගැඹුරු පිටපතක් අවශ්‍ය නම් copy.deepcopy () තවමත් යා යුතු මාර්ගයයි.


3
මෙය C ++ හි දර්ශකයන් මෙන් පෙනේ. කාර්යය ඉටු කිරීම සතුටක්, නමුත් කියවීමේ හැකියාව අනුව මම මේ ආකාරයේ ක්‍රියාකරුවන්ට අකමැතියි.
අර්නෙස්ටෝ

1
එයට එක්තරා ආකාරයක පෙනුමක් ඇත ... නමුත් බහු ශබ්ද කෝෂ ඒකාබද්ධ කරන විට, වාක්‍ය ඛණ්ඩය සුමට ලෙස පෙනේ.
පැබ්ටෝර්

2
ඒ ගැන සැලකිලිමත් වන්න, එය සිදු කරන්නේ නොගැඹුරු පිටපතක් පමණි.
සෙබස්තියන් ඇඳුම

ඔබ හරි e සෙබස්තියන් ඩ්‍රෙස්ලර්, මම වෙනස්කම් කරන්නම්. thnx.
පැබ්ටොරේ

2
සමහර කුළුබඩු සමඟ පිටපතක් සෑදීමට ඔබට අවශ්‍ය නම් ප්‍රයෝජනවත්:dict2 = {**dict1, 'key3':'value3'}
evg656e

49

පයිතන් 2.7 සහ 3 යන දෙඅංශයෙන්ම ආ ict ාවේ පිටපතක් නිර්මාණය කිරීමට හොඳම සහ පහසුම ක්‍රම වන්නේ ...

සරල (තනි මට්ටමේ) ශබ්ද කෝෂයේ පිටපතක් නිර්මාණය කිරීම සඳහා:

1. භාවිතා කරමින් dict () වෙනුවට පවතින dict යුතු කරුණු සැඳහුම ජනන ක්රමය.

my_dict1 = dict()
my_dict1["message"] = "Hello Python"
print(my_dict1)  # {'message':'Hello Python'}

my_dict2 = dict(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

2. පයිතන් ශබ්ද කෝෂයේ බිල්ට් යාවත්කාලීන () ක්‍රමය භාවිතා කිරීම.

my_dict2 = dict()
my_dict2.update(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

කැදැලි හෝ සංකීර්ණ ශබ්ද කෝෂයේ පිටපතක් සෑදීමට:

සාමාන්‍ය නොගැඹුරු සහ ගැඹුරු පිටපත් මෙහෙයුම් සපයන බිල්ට් පිටපත් මොඩියුලය භාවිතා කරන්න . මෙම මොඩියුලය පයිතන් 2.7 සහ 3 යන දෙඅංශයෙන්ම පවතී. *

import copy

my_dict2 = copy.deepcopy(my_dict1)

6
dict()නොගැඹුරු පිටපතක් ගැඹුරු පිටපතක් නොවන බව මම විශ්වාස කරමි . මෙයින් අදහස් කරන්නේ ඔබ කැදැල්ලක් ඇත්නම් dictපිටත dictපිටපතක් වන නමුත් අභ්‍යන්තර ආ ict ාව මුල් අභ්‍යන්තර ආ .ාවට යොමු කිරීමක් වනු ඇති බවයි.
shmuels

ඔව්, මෙම ක්‍රම දෙකම ගැඹුරු එකක් නොව නොගැඹුරු පිටපතක් නිර්මාණය කරයි. බලන්න, යාවත්කාලීන කළ පිළිතුර.
අකේ නිරලා

38

ඔබට ශබ්ද කෝෂ අවබෝධය සහිත නව ශබ්ද කෝෂයක් සෑදිය හැකිය. මෙය පිටපත ආයාත කිරීමෙන් වළක්වයි.

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

ඇත්ත වශයෙන්ම python> = 2.7 හි ඔබට කළ හැක්කේ:

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

නමුත් පසුගාමී අනුකූලතාව සඳහා, ඉහළම ක්‍රමය වඩා හොඳය.


4
හරියටම පිටපත් කරන්නේ කෙසේද සහ කුමක්ද යන්න පිළිබඳ වැඩි පාලනයක් ඔබට අවශ්‍ය නම් මෙය විශේෂයෙන් ප්‍රයෝජනවත් වේ. +1
ළඟා වීම

14
මෙම ක්‍රමය ගැඹුරු පිටපතක් සිදු නොකරන බවත්, යතුරු පිටපත් කිරීම පාලනය කිරීමට අවශ්‍ය නොවන නොගැඹුරු පිටපතක් ඔබට අවශ්‍ය නම්, d2 = dict.copy(d1)කිසිදු ආනයනයක් අවශ්‍ය නොවන බවත් සලකන්න .
ජැරෙක් පියර්කොව්ස්කි

1
@ ජරෙක්පියර්කොව්ස්කි: හෝ ඔබට ක්‍රමයක් වැනි ක්‍රමයක් අමතන්න:d2 = d1.copy()
අසාත් ඉබ්‍රකොව්

පළමු උදාහරණයේ දී ඔබට අවබෝධය අවශ්‍ය නොවන බව සලකන්න. dict.itemsදැනටමත් යතුරු / අගය යුගලයක් නැවත ලබා දිය හැකිය. එබැවින් ඔබට භාවිතා කළ හැකිය dict(mydict.items())(ඔබට ද භාවිතා කළ හැකිය dict(mydict)). ඔබට ඇතුළත් කිරීම් පෙරීමට අවශ්‍ය නම් අවබෝධය ලබා ගැනීම ප්‍රයෝජනවත් විය හැකිය.
පෝල් රූනි

27

සපයන ලද අනෙකුත් විසඳුම් වලට අමතරව, ඔබට **ශබ්ද කෝෂය හිස් ශබ්දකෝෂයකට ඒකාබද්ධ කිරීමට භාවිතා කළ හැකිය , උදා.

shallow_copy_of_other_dict = {**other_dict}.

දැන් ඔබට "නොගැඹුරු" පිටපතක් ලැබෙනු ඇත other_dict.

ඔබේ උදාහරණයට අදාළ වේ:

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

දර්ශකය: නොගැඹුරු සහ ගැඹුරු පිටපත් අතර වෙනස


1
මෙහි ප්‍රති results ලය වන්නේ ගැඹුරු පිටපතක් නොව නොගැඹුරු පිටපතකි.
sytech

1
මම මෙය උත්සාහ කළ නමුත් කරදරයක් විය. මෙය ක්‍රියාත්මක වන්නේ පයිතන් 3.5 සහ ඊට ඉහළින් පමණි. python.org/dev/peps/pep-0448
ThatGuyRob

21

පයිතන්හි පැවරුම් ප්‍රකාශයන් වස්තු පිටපත් නොකරයි, ඒවා ඉලක්කයක් සහ වස්තුවක් අතර බන්ධන නිර්මාණය කරයි.

එබැවින්, dict2 = dict1එය යොමු dict2කරන වස්තුව හා තවත් බන්ධනයක් ඇති dict1කරයි.

ඔබට ආ ict ාවක් පිටපත් කිරීමට අවශ්‍ය නම්, ඔබට එය භාවිතා කළ හැකිය 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')

ප්‍රති result ලය වන්නේ:

>>> 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']]

11

මෙය මා ද ව්‍යාකූල කළේ මුලදී මා පැමිණියේ සී පසුබිමකිනි.

C හි, විචල්‍යය යනු අර්ථ දක්වන ලද වර්ගයක් සහිත මතකයේ පිහිටීමකි. විචල්‍යයකට පැවරීම මඟින් දත්ත විචල්‍යයේ මතක ස්ථානයට පිටපත් කරයි.

නමුත් පයිතන්හි විචල්‍යයන් වස්තූන් වෙත යොමු කරන්නන් මෙන් ක්‍රියා කරයි. එබැවින් එක් විචල්‍යයක් තවත් විචල්‍යයකට පැවරීමෙන් පිටපතක් නොලැබේ, එමඟින් එම විචල්‍ය නාමය එකම වස්තුවකට යොමු කරයි.


5
python විචල්‍යයන් c ++
යොමුවලට

7
පයිතන්හි ඇති සියල්ල වස්තුවක් නිසා! diveintopython.net/getting_to_know_python/… (ඔව්, මෙම ප්‍රතිචාරය වසර ගණනාවක් ප්‍රමාදයි, නමුත් සමහර විට එය යමෙකුට යම් ප්‍රයෝජනයක් විය හැකිය!)
ග්‍රිමන්

1
පයිතන් භාෂා අර්ථ නිරූපණයන් පවසන්නේ "විචල්‍යයන්" නොමැති බවයි. ඒවා "නම් කරන ලද යොමු කිරීම්" ලෙස හැඳින්වේ; වස්තුවකට යොමු කිරීම යනු කේතයේ සින්ටැක්ටික් නූලකි. වස්තුවකට බොහෝ නම් තැබිය හැකිය. Ints, floats සහ str instance වැනි වෙනස් කළ නොහැකි වස්තූන් සතුව ඇත්තේ එක් ක්‍රියාවලියකට එක් අවස්ථාවක් පමණි. ඔබ මෙම myvalue = 1 myvalue = 2
DevPlayer

11

dictඅමතර යතුරු පද තර්ක සමඟ ඉදිකිරීම්කරු අමතා ඔබට අලුතින් ඉදිකරන ලද පිටපත එකවර පිටපත් කර සංස්කරණය කළ හැකිය :

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

8

පයිතන්හි සෑම විචල්‍යයක්ම (වැනි dict1හෝ strහෝ වැනි දේවල්__builtins__ මැෂිම තුල සමහර සඟවා ප්ලේටෝනියානු "වස්තුව" වෙත අවධානය යොමුකළ වේ.

ඔබ සකසන්නේ නම් dict1 = dict2, ඔබ යොමු dict1කරන්නේ එකම වස්තුවකට (හෝ මතක පිහිටීම හෝ ඔබ කැමති ඕනෑම ප්‍රතිසමයක්) ය dict2. දැන්, යොමු කරන ලද වස්තුව විසින්ම යොමු කරන dict1ලද එකම වස්තුව dict2වේ.

ඔබට පරීක්ෂා dict1 is dict2කළ හැකිය : විය යුතුය True. එසේම, සමාන id(dict1)විය යුතුය id(dict2).

ඔබට අවශ්‍යයි dict1 = copy(dict2), හෝ dict1 = deepcopy(dict2).

copyසහ අතර වෙනස deepcopy? (ඔබ එය ලැයිස්තුවකට යොමු කළාද?) හි deepcopyමූලද්‍රව්‍ය dict2ද පිටපත් බව සහතික කරයි.

මම deepcopyවැඩිපුර භාවිතා නොකරමි - සාමාන්‍යයෙන් අවශ්‍ය කේත ලිවීම දුර්වල පුරුද්දකි (මගේ මතය අනුව).


මම නිතරම ගැඹුරු පිටපතක් භාවිතා කළ යුතු බව මට වැටහී ඇති අතර එමඟින් මම කැදැලි ශබ්ද කෝෂයක් පිටපත් කර කැදැලි ඇතුළත් කිරීම් වෙනස් කිරීමට පටන් ගත් විට, ප්‍රති effects ල සිදුවන්නේ පිටපතට මිස මුල් පිටපතට නොවේ.
flutefreak7

7

dict1යනු යටින් පවතින ශබ්ද කෝෂ වස්තුවක් සඳහන් කරන සංකේතයකි. පවරා dict1ගැනීමට dict2හුදෙක් එකම යොමු පවරයි. 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)

6

dict2 = dict1ශබ්ද කෝෂය පිටපත් නොකරයි. dict2එකම ශබ්ද කෝෂයට යොමු වීමට එය ක්‍රමලේඛකයාට දෙවන ක්‍රමයක් ( ) ලබා දෙයි .


6
>>> dict2 = dict1
# dict2 is bind to the same Dict object which binds to dict1, so if you modify dict2, you will modify the dict1

ඩික්ට් වස්තුව පිටපත් කිරීමට බොහෝ ක්‍රම තිබේ, මම සරලවම භාවිතා කරමි

dict_1 = {
           'a':1,
           'b':2
         }
dict_2 = {}
dict_2.update(dict_1)

13
dict_2 = dict_1.copy()වඩා කාර්යක්ෂම හා තාර්කික ය.
ජීන්-ප්‍රංශුවා ෆැබ්රේ

2
Dict_1.copy () සමඟින් dict1 තුළ ඔබට ආ ict ාවක් තිබේ නම්, dict_2 හි අභ්‍යන්තර ආ ict ාව මත ඔබ කරන වෙනස්කම් dict_1 හි අභ්‍යන්තර විධානයට ද අදාළ වන බව සලකන්න. මෙම අවස්ථාවේදී ඔබ ඒ වෙනුවට copy.deepcopy (dict_1) භාවිතා කළ යුතුය.
පෝලිම්

5

ඔබ dict2 = dict1 කරන සෑම විටම, dict2 යන්නෙන් dict1 යන්නෙන් අදහස් කෙරේ. Dict1 සහ dict2 යන දෙකම මතකයේ එකම ස්ථානයකට යොමු කරයි. පයිතන් හි විකෘති වස්තූන් සමඟ වැඩ කරන අතරතුර මෙය සාමාන්‍ය අවස්ථාවකි. ඔබ පයිතන්හි විකෘති වස්තූන් සමඟ වැඩ කරන විට එය නිදොස් කිරීම දුෂ්කර බැවින් ඔබ ප්‍රවේශම් විය යුතුය.

Dict2 = dict1 භාවිතා කරනවා වෙනුවට, ඔබ dict1 වෙතින් dict2 වෙන් කිරීම සඳහා පයිතන්ගේ පිටපත් මොඩියුලයේ පිටපත් (නොගැඹුරු පිටපත) සහ ගැඹුරු පිටපත් ක්‍රමය භාවිතා කළ යුතුය .

නිවැරදි ක්‍රමය නම්:

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict1.copy()
>>> dict2
{'key1': 'value1', 'key2': 'value2'}
>>> dict2["key2"] = "WHY?"
>>> dict2
{'key1': 'value1', 'key2': 'WHY?'}
>>> dict1
{'key1': 'value1', 'key2': 'value2'}
>>> id(dict1)
140641178056312
>>> id(dict2)
140641176198960
>>> 

ඔබට හැඳුනුම්පත දැකිය හැකි පරිදි dict1 සහ dict2 යන දෙකෙහිම වෙනස් වේ, එයින් අදහස් වන්නේ දෙකම මතකයේ විවිධ ස්ථාන වෙත යොමු කිරීම / යොමු කිරීමයි.

මෙම විසඳුම වෙනස් කළ නොහැකි අගයන් සහිත ශබ්දකෝෂ සඳහා ක්‍රියා කරයි, විකෘති අගයන් ඇති අයට මෙය නිවැරදි විසඳුම නොවේ.

උදා:

>>> import copy
>>> dict1 = {"key1" : "value1", "key2": {"mutable": True}}
>>> dict2 = dict1.copy()
>>> dict2
{'key1': 'value1', 'key2': {'mutable': True}}
>>> dict2["key2"]["mutable"] = False
>>> dict2
{'key1': 'value1', 'key2': {'mutable': False}}
>>> dict1
{'key1': 'value1', 'key2': {'mutable': False}}
>>> id(dict1)
140641197660704
>>> id(dict2)
140641196407832
>>> id(dict1["key2"])
140641176198960
>>> id(dict2["key2"])
140641176198960

අපි dict1 සඳහා පිටපතක් යෙදුවද, විකෘති වල අගය dict2 සහ dict1 යන දෙඅංශයේම අසත්‍ය ලෙස වෙනස් කර ඇති බව ඔබට පෙනෙනු ඇත. මෙයට හේතුව වන්නේ අපි ඩික්ට් 1 හි විකෘති වූ කොටසක වටිනාකම වෙනස් කිරීමයි. අපි පිටපතක් පිටපතක් යොදන විට, එය කරන්නේ නොගැඹුරු පිටපතක් පමණක් වන අතර එයින් අදහස් කරන්නේ එය සියලු වෙනස් කළ නොහැකි අගයන් නව නියෝගයකට පිටපත් කරන අතර විකෘති අගයන් පිටපත් නොකරන නමුත් එය ඒවා යොමු කරනු ඇත.

අවසාන විසඳුම වන්නේ විකෘති අගයන් ඇතුළුව පිටපත් කරන ලද සියලු අගයන් සමඟ නව ආ ict ාවක් මුළුමනින්ම නිර්මාණය කිරීම සඳහා dict1 හි ගැඹුරු පිටපතක් කිරීමයි.

>>>import copy
>>> dict1 = {"key1" : "value1", "key2": {"mutable": True}}
>>> dict2 = copy.deepcopy(dict1)
>>> dict2
{'key1': 'value1', 'key2': {'mutable': True}}
>>> id(dict1)
140641196228824
>>> id(dict2)
140641197662072
>>> id(dict1["key2"])
140641178056312
>>> id(dict2["key2"])
140641197662000
>>> dict2["key2"]["mutable"] = False
>>> dict2
{'key1': 'value1', 'key2': {'mutable': False}}
>>> dict1
{'key1': 'value1', 'key2': {'mutable': True}}

ඔබට පෙනෙන පරිදි, හැඳුනුම්පත් වෙනස් වේ, එයින් අදහස් වන්නේ dict2 සම්පූර්ණයෙන්ම dict1 හි සියලු අගයන් සහිත නව නියෝගයක් බවයි.

මුල් ආ .ාවට බලපෑමක් නොකර විකෘති අගයන් කිසිවක් වෙනස් කිරීමට ඔබට අවශ්‍ය නම් ඩීප්කොපි භාවිතා කළ යුතුය. එසේ නොමැතිනම් ඔබට නොගැඹුරු පිටපතක් භාවිතා කළ හැකිය. මුල් පිටපතෙහි ඇති කැදැලි අගයන් පිටපත් කිරීම සඳහා පුනරාවර්තන ලෙස ක්‍රියා කරන නිසා ඩීප්කොපි සෙමින් මන්දගාමී වන අතර අමතර මතකයක් ද ගනී.


1

අනෙක් අය පැහැදිලි කර ඇති පරිදි, ගොඩනඟන ලද 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] = ..."

කරුණාකර මෙහි සාකච්ඡා කර ඇති lvalue වෙනස් කිරීමේ රටාව වෙත යොමු වන්න: පයිතන් 2.7 - lvalue වෙනස් කිරීම සඳහා පිරිසිදු වාක්‍ය ඛණ්ඩය . ප්රධාන නිරීක්ෂණ බව ය strසහ intPython වලින් අගයන් මෙන් හැසිරීමට (ඔවුන් ඇත්තටම ඒ අවටනම් යටතේ මා තුලද වස්තූන් ඉන්නේ වුවත්). ඔබ, ඒ කරුණාකර ද කිසිම දෙයක් නිරීක්ෂණය නිරීක්ෂණය කරන විටදී ගැන, භූගෝලීය පිහිටීම විශේෂ වේ strහෝ int. dictඑකම ආකාරයකින් භාවිතා කළ හැකි අතර ValueDict, අර්ථවත් වන බොහෝ අවස්ථා ගැන මට සිතිය හැකිය .


0

ගැඹුරු කේතයට වඩා 3 ගුණයකින් වේගවත් json සින්ටැක්ස් අනුගමනය කරන විධානයන්හි ඇති පහත කේතය

def CopyDict(dSrc):
    try:
        return json.loads(json.dumps(dSrc))
    except Exception as e:
        Logger.warning("Can't copy dict the preferred way:"+str(dSrc))
        return deepcopy(dSrc)

0

පංතියේ w / o ශබ්ද කෝෂයේ දේපල විචල්‍යයට අනුයුක්ත කිරීමට උත්සාහ කරන විට මම සුවිශේෂී හැසිරීමක් කරා දිව ගියෙමි

new = copy.deepcopy(my_class.a)එනම් යනාදිය වැඩ කරන්නේ නැහැ newනව්යනmy_class.a

නමුත් ඔබට කරන්න නම් old = my_class.aපසුව new = copy.deepcopy(old)එය එනම් වෙනස් කිරීමේදී ඉතා හොඳින් ක්රියා newබලපාන නීතියක් නොවේmy_class.a

මෙය සිදුවන්නේ ඇයිදැයි මට විශ්වාස නැත, නමුත් එය පැය කිහිපයක් ඉතිරි කර ගැනීමට උපකාරී වේ යැයි සිතමි! :)


ඉතින් ඔබ කොහොමද ගැඹුරු පිටපතක් කරන්නේ my_class.a?
ඇන්තනි

හොඳම ක්‍රමය නොවේ. හොඳ ප්‍රතිචාරයක් වන්නේ බෙලෝ ය.
ඩේවිඩ් බියුචමින්

-1

For loop භාවිතා කිරීමෙන් පිටපත් කිරීම:

orig = {"X2": 674.5, "X3": 245.0}

copy = {}
for key in orig:
    copy[key] = orig[key]

print(orig) # {'X2': 674.5, 'X3': 245.0}
print(copy) # {'X2': 674.5, 'X3': 245.0}
copy["X2"] = 808
print(orig) # {'X2': 674.5, 'X3': 245.0}
print(copy) # {'X2': 808, 'X3': 245.0}

1
මෙය ක්‍රියාත්මක වන්නේ සරල ශබ්ද කෝෂ සඳහා පමණි. deepcopyමෙම අරමුණු සඳහා පැහැදිලිවම ගොඩනගා ඇති ඇයි භාවිතා නොකරන්නේ ?
ඇන්තනි

හොඳම ක්‍රමය නොවේ. හොඳ ප්‍රතිචාරයක් වන්නේ බෙලෝ ය.
ඩේවිඩ් බියුචමින්

-6

ඔබට කෙලින්ම භාවිතා කළ හැකිය:

dict2 = eval(repr(dict1))

එහිදී object dict2 යනු dict1 හි ස්වාධීන පිටපතකි, එබැවින් ඔබට dict1 ට බලපෑමක් නොකර dict2 වෙනස් කළ හැකිය.

මෙය ඕනෑම ආකාරයක වස්තුවක් සඳහා ක්රියා කරයි.


4
මෙම පිළිතුර වැරදියි, එය භාවිතා නොකළ යුතුය. නිදසුනක් ලෙස, පරිශීලක-නිර්වචනය කරන ලද පන්තියකට __repr__එවාල් විසින් ප්‍රතිනිර්මාණය කිරීමට සුදුසුකමක් නොතිබිය හැකිය, නැතහොත් වස්තුවේ පන්තිය වර්තමාන විෂය පථයට කැඳවිය නොහැක. සාදන ලද වර්ග සමඟ ඇලී සිටියද, එකම වස්තුව විවිධ යතුරු යටතේ ගබඩා කර ඇත්නම් මෙය අසාර්ථක dict2වනු ඇත, එවිට වෙනම වස්තු දෙකක් ඇත. ස්වයං-යොමු කිරීමේ ශබ්දකෝෂයක, එහි dict1අඩංගු වන, ඒ වෙනුවට අඩංගු වේ Ellipsis. භාවිතා කිරීම වඩා හොඳ වනු ඇතdict1.copy()
එල්ඩ්රිච් චීස්

වස්තූන් (හෝ "සාරධර්ම") සෑම විටම චරිත නූල් මගින් විශ්වාසදායක නිරූපණයක් බලාපොරොත්තු නොවේ, සාමාන්‍යයෙන් මිනිස් කියවිය හැකි ආකාරයකින් නොවේ.
ඇලෙක්සි
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.