x = something_mutable
y = x
z = x
# sometime later make z reference something else, e.g. a list
my_list = [1, 2, 3]
# how to make x, y, z to reference my_list without using x and y explicitly
???
Is it possible? Not really going to use it, but curious.
Related question. How to erase the entire list/dictionary content and copy in place the entire content of another list/dictionary. I know开发者_StackOverflow how to do it, but curious how gurus would do it. Python is big and I just started learning it (trying hard no to code C in Python :)).
Thanks.
In answer to the first question: You can't do it, and if you could then you shouldn't.
In answer to the second question: For a list, a[:]=b
. For a dict, a.clear(); a.update(b)
.
The thing to remember about Python is that you have objects, which are chunks of data that are "out there" somewhere; and you have names that refer to some of those objects. Not all objects have names referring to them directly; for example, if you have a list full of other lists, strings, numbers, etc., usually only the outermost list will have a name referring to it; all the contained objects are accessed by doing things with the list.
It's important to understand this because it clarifies what's going on behind the scenes when you do things. If you del x
, that doesn't delete the object x
is referring to; it just deletes the name x
. If y
still refers to that object, that doesn't change. I don't think there's any way to directly delete an object; all you can do if remove all the references to it and let the garbage collector take care of it.
Likewise, if x
refers to something, then you reassign it, you're just telling the interpreter, "Ok, now I want x
to refer to this other object." The object x
used to refer to isn't affected (except that it might be garbage collected).
Consider this example:
def f(x, foo=[]):
foo.append(x)
return foo
This returns a list that grows every time you call f()
. On the other hand:
def f(x, foo=[]):
foo = foo + [x]
return foo
This doesn't work as expected. foo
used to refer to a list that was created when f()
was either defined or first called (I don't remember). Then we take that list, add another list to it to make a brand-new list, assign the new list to the name foo
, and return it. Next time we call f()
, foo
will be reassigned to that old empty list, which we didn't change last time.
Python's normal processes are designed in a way that doesn't allow to do what you want without creating special objects.
But Python is enough powerful to allow to create such objects as instances of a peculiar class whose behavior will be the desired one.
There are some complex points in the following code, but the instances of the class A are linked in manner that give them the behavior you want, and I see no other way to give them this collective behavior with more simplicity.
class A(dict):
li = []
def __init__(self,k = None,x = None):
weeth = ' empty'
if (k,x)!=(None,None) and type(x)==type(1):
weeth = ' with value '+repr(x+5)+' for key '+repr(k)
super(A, self).__setitem__(k,x+5)
A.li.append(self)
print '\n Instanciation of '+str(id(self))+weeth
def __setitem__(self,k,val):
if type(val)==type(1):
super(A, self).__setitem__(k,val+2)
print '\n Assignement of '+repr(val+2)+' to '+str(id(self))
also = [id(el) for el in A.li if el!=self]
for el in A.li:
if el!=self:
el.clear()
super(A, el).update(self)
el = self.items()
if also: print ' assignement done also for each of '+repr(also)
else:
print '\n Assignement of a non-integer '+repr(val)+' to '+str(id(self))+' : IMPOSSIBLE'
a = A('bn',12)
print 'A.li==',A.li
print 'a==',a
a[0] = 10
print 'a==',a
b =A()
print 'A.li==',A.li
print 'b==',b
c =A()
print 'A.li==',A.li
print 'c==',c
c['IMP'] = 'Elizabeth Taylor'
print 'c==',c
d =A('ZUI',103)
print 'A.li==',A.li
print 'd==',d
print '\na==',a
print 'b==',b
print 'c==',c
print 'd==',d
c['X45'] = 22
print 'a==',a
print 'b==',b
print 'c==',c
print 'd==',d
print '\n=========================================='
A.li = []
print "\nCreation of {'maize': 3, 'rice': 12, 'wheat': 7} with name 'x'"
x = A()
x['rice'] = 10
x['wheat'] = 5
x['maize'] = 1
print "\nCreation of {'yval':50} with name 'y' and {} with name 'z'"
y = A('yval',45)
z = A()
print '\nx==',x
print 'y==',y
print 'z==',z
print
def assign(d,dic):
d.update(dic)
k = d.iterkeys().next()
d[k] = d[k]
assign(z, {'kilo':123,'jili':14,'somoto':78})
print 'x==',x
print 'y==',y
print 'z==',z
result
Instanciation of 18527472 with value 17 for key 'bn'
A.li== [{'bn': 17}]
a== {'bn': 17}
Assignement of 12 to 18527472
a== {0: 12, 'bn': 17}
Instanciation of 18528232 empty
A.li== [{0: 12, 'bn': 17}, {}]
b== {}
Instanciation of 18528080 empty
A.li== [{0: 12, 'bn': 17}, {}, {}]
c== {}
Assignement of a non-integer 'Elizabeth Taylor' to 18528080 : IMPOSSIBLE
c== {}
Instanciation of 18528384 with value 108 for key 'ZUI'
A.li== [{0: 12, 'bn': 17}, {}, {}, {'ZUI': 108}]
d== {'ZUI': 108}
a== {0: 12, 'bn': 17}
b== {}
c== {}
d== {'ZUI': 108}
Assignement of 24 to 18528080
assignement done also for each of [18527472, 18528232, 18528384]
a== {'X45': 24}
b== {'X45': 24}
c== {'X45': 24}
d== {'X45': 24}
==========================================
Creation of {'maize': 3, 'rice': 12, 'wheat': 7} with name 'x'
Instanciation of 18528536 empty
Assignement of 12 to 18528536
Assignement of 7 to 18528536
Assignement of 3 to 18528536
Creation of {'yval':50} with name 'y' and {} with name 'z'
Instanciation of 18528688 with value 50 for key 'yval'
Instanciation of 18528840 empty
x== {'maize': 3, 'rice': 12, 'wheat': 7}
y== {'yval': 50}
z== {}
Assignement of 125 to 18528840
assignement done also for each of [18528536, 18528688]
x== {'somoto': 78, 'jili': 14, 'kilo': 125}
y== {'somoto': 78, 'jili': 14, 'kilo': 125}
z== {'kilo': 125, 'jili': 14, 'somoto': 78}
精彩评论