Re: new to python question
On Wed, Sep 28, 2011 at 5:06 PM, The Geek theg...@gmail.com wrote: I'm clearly not understanding something about scope in python... Any help is appreciated In the following script I'm attempting to create 2 Foo objects, for each Foo object I create 2 Bars and add them to Foo's bar array Something hokey is occurring with the foo.bars.append(bar) line such that Foo.bars is treated as a static (I know python doesn't have statics) I have a workaround using encapsulation for the bars array but I prefer would also like to understand the issue. TIA, Brad [SCRIPT] foos = [] class Foo: id = 0 bars = [] class Bar: id = 0 for j in range(0, 2): foo = Foo() for i in range(0, 2): bar = Bar() bar.id = i foo.bars.append(bar) foos.append(foo) for myFoo in foos: print(foo id: , myFoo.id) for myBar in myFoo.bars: print (\tbar id: , myBar.id) [/SCRIPT] It's a pretty common gotcha for people coming from other languages. Everything declared in the class scope becomes an attribute of the class. class Foo(object) : ...a = 3 ...def b() : pass ... dir(Foo) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_ _weakref__', 'a', 'b'] Mutating those objects mutates the attribute of the class, which is visible to all instances of the class. In order to get an instance of a class, you have to add the field to the instance of the class instead of to the class itself. class Bar(object) : def ___init__(self) : self.a = 3 -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
Bernd Nawothnig wrote: You're thinking you're passing the arguments as reference That is the way Fortran handles them: which is one of the things you really love when you link against underdocumented Fortran programs from C. (is that parameter a scalar or an array? crash! oh, an array. how many values does it expect? crash! oh, a few more, I suppose). /F -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
On Sun, 15 May 2005 08:00:47 +0200, Fredrik Lundh [EMAIL PROTECTED] wrote: M.E.Farmer wrote: I said exactly what I meant, the parentheses around the values creates a tuple that you have no reference to! repeating it doesn't make you right; no extra tuple is created, and the parens are part of the syntax: If the target is a target list enclosed in parentheses or in square brackets: The object must be a sequence with the same number of items as there are targets in the target list, and its items are assigned, from left to right, to the corresponding targets. http://docs.python.org/ref/assignment.html (originally, you had to use [] to unpack lists, and () or no parens only worked for tuples. the ability to use an arbitrary sequence was added in 1.5) Note that (x) without a comma doesn't unpack like [x] however: (x)= 123, x (123,) [x]= 123, x 123 (x,)= 123, x 123 x,= 123, x 123 Also, BTW, 123, (123,) [123,] [123] I.e., that last result is not [(123,)] There's actually a bunch of context-sensitive things about commas that you just have to get used to, in lists, tuples, function call arg lists, subscripts (__getitem__ args), unpacking assignment targets, etc. on the other hand, the function you're calling in this example *does* create a tuple that you have no reference to after the assignment. Yeah, but it would create that tuple whether there was an assignment of the returned result or not. Collecting unconnected facts in one breath remind me too much of political speeches ;-) that doesn't matter, of course, since the tuple is removed by the garbage collector immediately after it has been unpacked. I'm too tired to figure a humorous segue ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
No. You claimed quote This will only create a tuple in memory /quote That is not what I said please do not edit my words and call it a quote! But we just learned that this is not the case. Yes it seems I was proven wrong and have learned much from the discussion ;) That is why I am here to learn from others and help if I can ( sometimes I am just plain wrong and I get the help ) Reduced to this argument I have no objection. Glad to hear it. Lisp is far from being ugly ;-) Your words not mine.I never said it was ugly. Lisp is beautiful but Python isn't Lisp, and the () *are* getting overloaded. M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
Fredrik and Bengt: Thank you for the time. I will study the docs and play with the shell till this is firm. M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
It looks like the docs could use some examples of the various assignments it refers to. I think something like Bengt posted would be a nice addition if it included assignments with slices and dicts too. Just a thought. M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
A new to Python question
Hi I'm trying to teach myself python and so far to good, but I'm having a bit of trouble getting a function to work the way I think it should work. Right now I'm taking a simple program I wrote in Fortran and trying to do it in Python. I got it to work, but now I'm trying to modularize it. My fortran program uses a subroutine and I was trying to do the same thing in Python. But I'm still new so I'm having trouble understanding what I'm doing wrong. Here is my code: #! /usr/bin/python #This program takes two vectors and multiplies them #against a 10X10 array. It also then gives the dot product, #sum, and max value of the array. import Numeric def abc(array1,array2,dotprod,sum,maxvalue): Takes two arrays and performs predetermined calculations, Then returns the solutions back as the same array, along with the dot product, sum, and max value of the array. #TODO: Get this damn thing working!! print Array 1 in:,array1 #Debug data = Numeric.zeros((10,10)) for i in range(10): for j in range(10): data[i,j] = (i+1)+(j+1) e = Numeric.matrixmultiply(data, array1) g = Numeric.matrixmultiply(Numeric.transpose(data),array2) array1 = e array2 = g dotprod = Numeric.dot(array1,array2) sum = Numeric.sum(array1) maxvalue = array2[Numeric.argmax(array2)] print Array 1 out:,array1 #Debug return array1,array2,dotprod,sum,maxvalue #-- Not working as I thought it would. x = Numeric.arange(1,11) y = Numeric.arange(1,11)*2 dotp,sumx,maxv = 0,0,0 #Is this the only way to declare a variable? print 'Array X:',x print 'Array Y:',y abc(x,y,dotp,sumx,maxv) print 'Calling function abc' print 'Array X:',x print 'Array Y:',y print 'Dot Product of X and Y:',dotp print 'Sum of array X:',sumx print 'Max value of array Y:',maxv If you run it the data gets passed to the function just fine and it finds the right numbers. Its just getting it to pass them back thats not working. I put some print statements inside the function just to see how the data gets passed. So any ideas that would help me? If you want to see the fortran code just email me. David -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
On 2005-05-14, David wrote: abc(x,y,dotp,sumx,maxv) (x,y,dotp,sumx,maxv) = abc(x,y,dotp,sumx,maxv) Bernd -- Those who desire to give up freedom in order to gain security, will not have, nor do they deserve, either one. [T. Jefferson] -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
Hi, You're thinking you're passing the arguments as reference (look at mutable vs non-mutable) Your function returns the values in a tupple (x,y,...); you need to fetch the values from that tupple Regards, Philippe David wrote: Hi I'm trying to teach myself python and so far to good, but I'm having a bit of trouble getting a function to work the way I think it should work. Right now I'm taking a simple program I wrote in Fortran and trying to do it in Python. I got it to work, but now I'm trying to modularize it. My fortran program uses a subroutine and I was trying to do the same thing in Python. But I'm still new so I'm having trouble understanding what I'm doing wrong. Here is my code: #! /usr/bin/python #This program takes two vectors and multiplies them #against a 10X10 array. It also then gives the dot product, #sum, and max value of the array. import Numeric def abc(array1,array2,dotprod,sum,maxvalue): Takes two arrays and performs predetermined calculations, Then returns the solutions back as the same array, along with the dot product, sum, and max value of the array. #TODO: Get this damn thing working!! print Array 1 in:,array1 #Debug data = Numeric.zeros((10,10)) for i in range(10): for j in range(10): data[i,j] = (i+1)+(j+1) e = Numeric.matrixmultiply(data, array1) g = Numeric.matrixmultiply(Numeric.transpose(data),array2) array1 = e array2 = g dotprod = Numeric.dot(array1,array2) sum = Numeric.sum(array1) maxvalue = array2[Numeric.argmax(array2)] print Array 1 out:,array1 #Debug return array1,array2,dotprod,sum,maxvalue #-- Not working as I thought it would. x = Numeric.arange(1,11) y = Numeric.arange(1,11)*2 dotp,sumx,maxv = 0,0,0 #Is this the only way to declare a variable? print 'Array X:',x print 'Array Y:',y abc(x,y,dotp,sumx,maxv) print 'Calling function abc' print 'Array X:',x print 'Array Y:',y print 'Dot Product of X and Y:',dotp print 'Sum of array X:',sumx print 'Max value of array Y:',maxv If you run it the data gets passed to the function just fine and it finds the right numbers. Its just getting it to pass them back thats not working. I put some print statements inside the function just to see how the data gets passed. So any ideas that would help me? If you want to see the fortran code just email me. David -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
On 2005-05-14, Philippe C. Martin wrote: You're thinking you're passing the arguments as reference That is the way Fortran handles them: [...] Right now I'm taking a simple program I wrote in Fortran Bernd -- Those who desire to give up freedom in order to gain security, will not have, nor do they deserve, either one. [T. Jefferson] -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
David wrote: Hi I'm trying to teach myself python and so far to good, but I'm having a bit of trouble getting a function to work the way I think it should work. Right now I'm taking a simple program I wrote in Fortran and trying to do it in Python. I got it to work, but now I'm trying to modularize it. My fortran program uses a subroutine and I was trying to do the same thing in Python. But I'm still new so I'm having trouble understanding what I'm doing wrong. Here is my code: #! /usr/bin/python #This program takes two vectors and multiplies them #against a 10X10 array. It also then gives the dot product, #sum, and max value of the array. import Numeric def abc(array1,array2,dotprod,sum,maxvalue): Takes two arrays and performs predetermined calculations, Then returns the solutions back as the same array, along with the dot product, sum, and max value of the array. #TODO: Get this damn thing working!! print Array 1 in:,array1 #Debug data = Numeric.zeros((10,10)) for i in range(10): for j in range(10): data[i,j] = (i+1)+(j+1) e = Numeric.matrixmultiply(data, array1) g = Numeric.matrixmultiply(Numeric.transpose(data),array2) array1 = e array2 = g dotprod = Numeric.dot(array1,array2) sum = Numeric.sum(array1) maxvalue = array2[Numeric.argmax(array2)] print Array 1 out:,array1 #Debug return array1,array2,dotprod,sum,maxvalue #-- Not working as I thought it would. x = Numeric.arange(1,11) y = Numeric.arange(1,11)*2 dotp,sumx,maxv = 0,0,0 #Is this the only way to declare a variable? print 'Array X:',x print 'Array Y:',y abc(x,y,dotp,sumx,maxv) print 'Calling function abc' print 'Array X:',x print 'Array Y:',y print 'Dot Product of X and Y:',dotp print 'Sum of array X:',sumx print 'Max value of array Y:',maxv If you run it the data gets passed to the function just fine and it finds the right numbers. Its just getting it to pass them back thats not working. I put some print statements inside the function just to see how the data gets passed. So any ideas that would help me? If you want to see the fortran code just email me. David Hello David, welcome to Python! Python always returns 'something' from a function or method if nothing is specified or there is no return you get an implicit None. You have created a function that accepts a few arguments and processes them then returns there value. The problem is that you **have not** used the return values ;) example: def funk(first,second,third): return first,second,third This can be like this: print funk(theses three args can be anything,2,three) If you need to use the return values you need to assign them to a name so you have a handle on them. Variables are don't exist in Python there are only objects and names( hence namespaces ), but not everyone is so strict and you still see mention of 'variables' when they mean 'names'. ##dotp,sumx,maxv = 0,0,0 # not needed here print 'Array X:',x print 'Array Y:',y ## Notice we assign the return values to names so we can access it later arr1,arr2,dotp,sumx,maxv = abc(x,y,0,0,0) print 'Calling function abc' print 'Array X:',arr1 print 'Array Y:',arr2 print 'Dot Product of X and Y:',dotp print 'Sum of array X:',sumx print 'Max value of array Y:',maxv Or you could pack all return values into a tuple and access it thru slices. ##dotp,sumx,maxv = 0,0,0 # not needed here print 'Array X:',x print 'Array Y:',y abcinfo = abc(x,y,0,0,0) print 'Calling function abc' print 'Array X:',abcinfo[0] print 'Array Y:',abcinfo[1] print 'Dot Product of X and Y:',abcinfo[2] print 'Sum of array X:',abcinfo[3] print 'Max value of array Y:',abcinfo[4] Or you could use a dictionary, or etc... The possibilities are endless. Be sure to study up on namespaces, it will ease your Python woes. Namespaces are the most fundamental part of Python that new users don't understand. Namespace mastery will take you far. Just remember there are only two scopes local and global ;) http://docs.python.org hth, M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
(x,y,dotp,sumx,maxv) = abc(x,y,dotp,sumx,maxv) This will only create a tuple in memory that has no name to reference it by! How would you access the returned value? If you want a tuple you need to assign all the return vales to a single name. mytup = abc(x,y,dotp,sumx,maxv) M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
M.E.Farmer wrote: (x,y,dotp,sumx,maxv) = abc(x,y,dotp,sumx,maxv) This will only create a tuple in memory that has no name to reference it by! Huh? This binds the names x, y, dotp, sumx and maxv to the values returned by abc: py def abc(*args): ... return args ... py (x,y,dotp,sumx,maxv) = abc(2,3,5,7,11) py x 2 py y 3 py dotp 5 py sumx 7 py maxv 11 Of course, the parentheses around x,y,dotp,sumx,maxv are unnecessary. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
Thank you very much. Tulpes are really neat now that I've looked at them. So after just fixing it, I changed it up and I would like to show it off now. #! /usr/bin/python #This program takes two vectors and multiplies them #against a 10X10 array. It also then gives the dot product, #sum, and max value of the array. import Numeric def abc(package): Takes two arrays and performs predetermined calculations, Then returns the solutions back as the same array, along with the dot product, sum, and max value of the array. Data slots: 0 - First Array 1 - Second Array 2 - Dot product 3 - Sum 4 - Max Value f = Numeric.zeros((10,10)) for i in range(10): for j in range(10): f[i,j] = (i+1)+(j+1) e = Numeric.matrixmultiply(f, package[0]) g = Numeric.matrixmultiply(Numeric.transpose(f),package[1]) package[0] = e package[1] = g package[2] = Numeric.dot(package[0],package[1]) package[3] = Numeric.sum(package[0]) package[4] = package[1][Numeric.argmax(package[1])] return package data = [Numeric.arange(1,11),Numeric.arange(1,11)*2,0,0,0] #data = [Array X, Array Y, Dot product, Sum, Max Value] print 'Array X:',data[0] print 'Array Y:',data[1] data = abc(data) print 'Calling function abc' print 'Array X:',data[0] print 'Array Y:',data[1] print 'Dot Product of X and Y:',data[2] print 'Sum of array X:',data[3] print 'Max value of array Y:',data[4] I think its just wonderful now, but if you got any other suggestions, Please do tell. Thanks everyone. David -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
Hmm don't know what happened. I guess the formatting got all chewed up. -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
On 2005-05-14, M.E.Farmer wrote: (x,y,dotp,sumx,maxv) = abc(x,y,dotp,sumx,maxv) This will only create a tuple in memory that has no name to reference it by! Maybe. But it does not seem to hurt. And I am not sure the tupel _is_ really created in that situation. How would you access the returned value? If you want a tuple you need to assign all the return vales to a single name. We do not want the tuple. Python 2.3.5 (#1, Apr 28 2005, 12:14:04) [GCC 3.4.3-20050110 (Gentoo Linux 3.4.3.20050110-r2, ssp-3.4.3.20050110-0, pie- on linux2 Type help, copyright, credits or license for more information. def foo(): ... return 1,2,3 ... (a,b,c)=foo() print a,b,c 1 2 3 works. Of course, you can omit the (): a,b,c=foo() print a,b,c 1 2 3 That makes no difference. Bernd -- Those who desire to give up freedom in order to gain security, will not have, nor do they deserve, either one. [T. Jefferson] -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
Yes, I gathered. We all get our habits from somewhere :-) Regards, Philippe Bernd Nawothnig wrote: On 2005-05-14, Philippe C. Martin wrote: You're thinking you're passing the arguments as reference That is the way Fortran handles them: [...] Right now I'm taking a simple program I wrote in Fortran Bernd -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
I said exactly what I meant, the parentheses around the values creates a tuple that you have no reference to! It also has a side effect of binding the names inside the tuple to a value and placing them in the local namespace( implicit tuple unpacking ). It might be the same as no parens but it isn't very clear. If you want a tuple make it explicit, if you want individual names make it explicit. def f(q,w,e,r): ... return q,w,e,r ... # diff names a,b,c,d= f(1,2,3,4)# explicit tuple unpacking dir() ['__builtins__', '__doc__', '__name__', 'a', 'b', 'c', 'd', 'f', 'shell'] del a,b,c,d # where is the tuple (a,b,c,d)= f(1,2,3,4)# implicit tuple unpacking !? dir() ['__builtins__', '__doc__', '__name__', 'a', 'b', 'c', 'd', 'f', 'shell'] del a,b,c,d # Where is the tuple (a,s,d,f)? There isn't one. # assign to a single name ( don't do tuple unpacking ) tup=f(1,2,3,4) dir() ['__builtins__', '__doc__', '__name__', 'f', 'shell', 'tup'] Now there is. Steve since you are closer to expert than novice you understand the difference. I feel this can be confusing to newbies, maybe you disagree. M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
I said exactly what I meant, the parantheses around the values creates a tuple that you have no reference to! It also has a side effect of binding the names inside the tuple to a value and placing them in the local namespace. It might be the same but it isn't very clear. If you want a tuple make it explicit, if you want individual names make it explicit. def f(q,w,e,r): ... return q,w,e,r ... # diff names a,b,c,d= f(1,2,3,4)# explicit tuple unpacking dir() ['__builtins__', '__doc__', '__name__', 'a', 'b', 'c', 'd', 'f', 'shell'] del a,b,c,d # where is the tuple (a,b,c,d)= f(1,2,3,4)# implicit tuple unpacking !? dir() ['__builtins__', '__doc__', '__name__', 'a', 'b', 'c', 'd', 'f', 'shell'] del a,b,c,d # Where is the tuple (a,b,c,d)? There isn't one. # assign to a single name ( don't do tuple unpacking ) tup=f(1,2,3,4) dir() ['__builtins__', '__doc__', '__name__', 'f', 'shell', 'tup'] Now there is. Steve since you are closer to expert than novice you understand the difference. I feel this can be confusing to newbies, maybe you disagree. M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
M.E.Farmer wrote: I said exactly what I meant, the parentheses around the values creates a tuple that you have no reference to! It also has a side effect of binding the names inside the tuple to a value and placing them in the local namespace( implicit tuple unpacking ). It might be the same as no parens but it isn't very clear. If you want a tuple make it explicit, if you want individual names make it explicit. It actually is the same, and I don't think implicit or explicit is the difference you should be citing here. The parentheses are fully optional -- they don't change the semantics at all: py t = (4, 5) py a = t py a is t True py a = (b, c) = t py a is t True py a = b, c = t py a is t True In all cases, a still gets assigned the tuple (4, 5). Whether or not you put the parentheses around b, c is fully a matter of style. I don't know the implementation enough to know whether or not a tuple is actually created when b and c are bound to their values, but I'd be willing to bet that whatever happens to (b, c) is exactly the same as what happens to b, c. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
Steven Bethard wrote: I don't know the implementation enough to know whether or not a tuple is actually created when b and c are bound to their values, but I'd be willing to bet that whatever happens to (b, c) is exactly the same as what happens to b, c. Some corroborating evidence: py def f(t): ... (b, c) = t ... py def g(t): ... b, c = t ... py import dis py dis.dis(f) 2 0 LOAD_FAST0 (t) 3 UNPACK_SEQUENCE 2 6 STORE_FAST 2 (b) 9 STORE_FAST 1 (c) 12 LOAD_CONST 0 (None) 15 RETURN_VALUE py dis.dis(g) 2 0 LOAD_FAST0 (t) 3 UNPACK_SEQUENCE 2 6 STORE_FAST 2 (b) 9 STORE_FAST 1 (c) 12 LOAD_CONST 0 (None) 15 RETURN_VALUE They're both an UNPACK_SEQUENCE byte-code. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
On 14 May 2005 10:44:30 -0700, M.E.Farmer [EMAIL PROTECTED] wrote: [...] Be sure to study up on namespaces, it will ease your Python woes. Namespaces are the most fundamental part of Python that new users don't understand. Namespace mastery will take you far. Just remember there are only two scopes local and global ;) And don't jump to conclusions when you read a line like the last above ;-) I.e., there can be many different local and global scopes, not just one of each, and since Python is a very dynamic language, existence of things can vary with execution time and logic, so those scopes don't all have to exist at the same time, or at all, nor persist until the program runs to its end. Also, ISTM local is probably being stretched a little above to include nested scopes, which are a bit different from either plain local or global in how you can access them. I would second the advice to explore namespaces, and particularly attribute name spaces such as are defined by classes. Attribute access and descriptors conspire to enable much of the magic you can cook up with Python, as well as stuff that happens automatically. In short, a whole unopened deluxe set of programming Legos is at your elbow, besides the pieces you have encountered so far. Have fun ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
On 14 May 2005 13:25:55 -0700, M.E.Farmer [EMAIL PROTECTED] wrote: I said exactly what I meant, the parentheses around the values creates a tuple that you have no reference to! It also has a side effect of I don't understand what you are saying, or meaning ;-) BTW, the function call has nothing to do with what happens on the left hand side of the assignment. It is only the result of the function call that counts, so we could as well use a literal or other expression. This is a matter of unpacking a sequence according to the left hand target. E.g., iter([1,2,3]) listiterator object at 0x02F8F68C a,b,c = iter([1,2,3]) d,e,f = [1,2,3] g,h,i = 'GHI' [a,b,c,d,e,f,g,h,i] [1, 2, 3, 1, 2, 3, 'G', 'H', 'I'] Ok, now looking at the code for the assignment to a,b,c vs to (a,b,c): import dis dis.dis(compile('(a,b,c) = iter([1,2,3])','','exec')) 1 0 LOAD_NAME0 (iter) 3 LOAD_CONST 0 (1) 6 LOAD_CONST 1 (2) 9 LOAD_CONST 2 (3) 12 BUILD_LIST 3 15 CALL_FUNCTION1 18 UNPACK_SEQUENCE 3 21 STORE_NAME 1 (a) 24 STORE_NAME 2 (b) 27 STORE_NAME 3 (c) 30 LOAD_CONST 3 (None) 33 RETURN_VALUE dis.dis(compile('a,b,c = iter([1,2,3])','','exec')) 1 0 LOAD_NAME0 (iter) 3 LOAD_CONST 0 (1) 6 LOAD_CONST 1 (2) 9 LOAD_CONST 2 (3) 12 BUILD_LIST 3 15 CALL_FUNCTION1 18 UNPACK_SEQUENCE 3 21 STORE_NAME 1 (a) 24 STORE_NAME 2 (b) 27 STORE_NAME 3 (c) 30 LOAD_CONST 3 (None) 33 RETURN_VALUE I don't see anything in the code about creating a tuple that you have no reference to. To see the unpacking of GHI so as to get rid of the function call red herring: dis.dis(compile('a,b,c = GHI','','exec')) 1 0 LOAD_CONST 0 ('GHI') 3 UNPACK_SEQUENCE 3 6 STORE_NAME 0 (a) 9 STORE_NAME 1 (b) 12 STORE_NAME 2 (c) 15 LOAD_CONST 1 (None) 18 RETURN_VALUE dis.dis(compile('(a,b,c) = GHI','','exec')) 1 0 LOAD_CONST 0 ('GHI') 3 UNPACK_SEQUENCE 3 6 STORE_NAME 0 (a) 9 STORE_NAME 1 (b) 12 STORE_NAME 2 (c) 15 LOAD_CONST 1 (None) 18 RETURN_VALUE ISTM the assignment part starts with UNPACK_SEQUENCE and all the code looks the same. BTW, UIAM it is the commas that define tuples, so the outermost parens are really expression parens more than tuple syntax. But note that you can have nested tuple structure as target, and that does change the unpacking code (and what it expects to have available to unpack): (x,(y,z)) = 'XYZ' Traceback (most recent call last): File stdin, line 1, in ? ValueError: too many values to unpack (x,(y,z)) = 'X','YZ' x 'X' y 'Y' z 'Z' (x,(y,z)) = [1, [2,3]] x 1 y 2 z 3 dis.dis(compile('(x,(y,z)) = 0','','exec')) 1 0 LOAD_CONST 0 (0) 3 UNPACK_SEQUENCE 2 6 STORE_NAME 0 (x) 9 UNPACK_SEQUENCE 2 12 STORE_NAME 1 (y) 15 STORE_NAME 2 (z) 18 LOAD_CONST 1 (None) 21 RETURN_VALUE Obviously we can't unpack the zero, but the code doesn't know that until it tries it, so we can look at what the left hand side code is independent of the right hand side. binding the names inside the tuple to a value and placing them in the local namespace( implicit tuple unpacking ). It might be the same as no parens but it isn't very clear. If you want a tuple make it explicit, if you want individual names make it explicit. OTOH, you might want a mix: a, tup, (b,c), d = ['A', ('a', 'tuple'), 'BC', 'Sandra'] a 'A' tup ('a', 'tuple') b 'B' c 'C' d 'Sandra' Or with gratuitous _outer_ parens: (a, tup, (b,c), d) = ['A', ('a', 'tuple'), 'BC', 'Sandra'] a 'A' tup ('a', 'tuple') b 'B' c 'C' d 'Sandra' dis.dis(compile(a, tup, (b,c), d = ['A', ('a', 'tuple'), 'BC', 'Sandra'],'','exec')) 1 0 LOAD_CONST 0 ('A') 3 LOAD_CONST 6 (('a', 'tuple')) 6 LOAD_CONST 3 ('BC') 9 LOAD_CONST 4 ('Sandra') 12
Re: A new to Python question
It actually is the same, and I don't think implicit or explicit is the difference you should be citing here. Why not it is relevant and true that Python is doing an implicit unpacking of the values in that unnamed tuple. Quoting myself It might be the same as no parens but it isn't very clear. If you want a tuple make it explicit, if you want individual names make it explicit. So as you say, maybe it is is fully a matter of style and apparently I don't like that style! They're both an UNPACK_SEQUENCE byte-code. I have dissed it myself ;) My argument, if you can call it that, is that it is not clear that Python is going to do a tuple unpacking here or not ! You had to dis it to find out and you are not a newbie. # extra fluff from pyshell import dis dis.dis(compile('(x,y,dotp,sumx,maxv) = abc(x,y,dotp,sumx,maxv)','','exec')) 0 SET_LINENO 0 3 SET_LINENO 1 6 LOAD_NAME0 (abc) 9 LOAD_NAME1 (x) 12 LOAD_NAME2 (y) 15 LOAD_NAME3 (dotp) 18 LOAD_NAME4 (sumx) 21 LOAD_NAME5 (maxv) 24 CALL_FUNCTION5 27 UNPACK_SEQUENCE 5 30 STORE_NAME 1 (x) 33 STORE_NAME 2 (y) 36 STORE_NAME 3 (dotp) 39 STORE_NAME 4 (sumx) 42 STORE_NAME 5 (maxv) 45 LOAD_CONST 0 (None) 48 RETURN_VALUE dis.dis(compile('x,y,dotp,sumx,maxv = abc(x,y,dotp,sumx,maxv)','','exec')) 0 SET_LINENO 0 3 SET_LINENO 1 6 LOAD_NAME0 (abc) 9 LOAD_NAME1 (x) 12 LOAD_NAME2 (y) 15 LOAD_NAME3 (dotp) 18 LOAD_NAME4 (sumx) 21 LOAD_NAME5 (maxv) 24 CALL_FUNCTION5 27 UNPACK_SEQUENCE 5 30 STORE_NAME 1 (x) 33 STORE_NAME 2 (y) 36 STORE_NAME 3 (dotp) 39 STORE_NAME 4 (sumx) 42 STORE_NAME 5 (maxv) 45 LOAD_CONST 0 (None) 48 RETURN_VALUE dis.dis(compile('tup = abc(x,y,dotp,sumx,maxv)','','exec')) 0 SET_LINENO 0 3 SET_LINENO 1 6 LOAD_NAME0 (abc) 9 LOAD_NAME1 (x) 12 LOAD_NAME2 (y) 15 LOAD_NAME3 (dotp) 18 LOAD_NAME4 (sumx) 21 LOAD_NAME5 (maxv) 24 CALL_FUNCTION5 27 STORE_NAME 6 (tup) 30 LOAD_CONST 0 (None) 33 RETURN_VALUE You may notice that the act of assigning the return values to a unnamed tuple and a name have different semantics and that was the real point. The problem is why should this be the same: a,b,c=(1,2,3) (a,b,c)=(1,2,3) Seems weird, non-intuitive that a tuple unpacking and tuple creation have the same bytecode. So why is this done? What is the reason, I am sure there are a few ;) p.s. I am leaving out for a while and will read/followup later if needed. Thank you all for your time. M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
I explained what i meant in previous post there was nothing more than just a discussion I have no real problem here just more of a sore point in style for me. I feel that parens are quite overloaded and it can be confusing to newbies. But if the parens are just fluff then get rid of them, it is clearer * at least to me * ;) There are enough things wrapped in parens nowadays it is starting to look like lisp. BTW, UIAM it is the commas that define tuples, so the outermost parens are really expression parens more than tuple syntax. Hadn't really thought of that way but it makes sense w = 1,2,3 w.__doc__ tuple() - an empty tuple tuple(sequence) - tuple initialized from sequence's items If the argument is a tuple, the return value is the same object. Thanks for your time Bengt! M.E.Farmer -- http://mail.python.org/mailman/listinfo/python-list
Re: A new to Python question
M.E.Farmer [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] But if the parens are just fluff then get rid of them, it is clearer * at least to me * ;) While I find unnecessary parens on the right of '=' tolerable, I agree as to the style preference. Terry J. Reedy -- http://mail.python.org/mailman/listinfo/python-list