Danny Yoo wrote: || Am I missing some other usage where you wouldn't want to unpack the || *arg? If not, would the following "behind the scenes" behavior be || possible/preferred? || || ### || def foo(*arg): || pass || ### || || automatically does this || || ### || def foo(*arg): || if len(arg) == 1: || arg = arg[0] || pass || ### | | | Yes: what if we're passing foo() some mixed data? This might not be | as weird as it might sound: imagine that a cartegian point [x, y] is | represented either as a point: | | [x, y] | | or as a single x coordinate number x where the y coordinate is | assumed to be zero. | | x | | Our list would then contain a mix of data. For example, a list with | the points (4, 3) and (5, 0) and (2, 9) could be represented as: | | [[4, 3], 5, [2, 9]] | [cut] | But if we pass playConnectTheDots() with a single point, we want the | function not to automatically unpack the argument as if it were | something else: it would be a lossy kind of implicit transformation. |
OK, I think it's becoming clear. I should think of the *arg in the receiving function as containing a list of things that were sent to it (actually, a tuple). I am likely confusing things a bit because I want to be able to receive an x,y coordinate as foo(x,y) rather than something like foo((x,y)). | If the case of len(points) == 1 is treated as a special case, that | would make the logic turn into... well, I don't know, it would be | ambiguous! | As I understand it now, reducing it to a single point rather than leaving it as a tuple of length 1 destroys ones ability to iterate over the items that were passed in. e.g. if you call foo(42) and foo has a *args as its only argument, them automatcally changine the received value of (42, ) to 42 would destroy the ability to loop over args as ### for arg in args: #do something ### As many times as I would prefer to have len == 1 arguments unpacked, if *args automatically behaved this way then likely the other half of the user-universe would be packing up things that have length 0 so they could iterate over them ;-) ### if len(args) == 0: args = (args, ) ### | From the example above, if we did feed it: | | playConnectTheDots([[4, 3]]) ## Draw the point (4, 3) | | vs: | | playConnectTheDots([4, 3]) ## Draw between (4, 0) and (3, 0) | | then imagine what would happen if Python did the kind of automatic | unwrapping you're thinking of. How would it tell the difference | between these two different cases? | If playConnectTheDots looks like this, ### def playConnectTheDots(*points): if len(points) == 1: points = points[0] for point in points: x,y = getX(point),getY(point) print 'plot %s %s' % (x,y) ### then I imagine it will work exactly as you are describing :-) I think you meant to call the function like this, ### playConnectTheDots(*[[4, 3]]) playConnectTheDots(*[4, 3]) ### if the function is defined as this: ### def playConnectTheDots(*points): for point in points: x,y = getX(point),getY(point) print 'plot %s %s' % (x,y) ### How would you have written the first line(s) of playConnectTheDots? Or did you mean to pass the values like this: ### playConnectTheDots(4, 3) #plot 4,0 and 3,0 playConnectTheDots([4, 3]) #plot 4,3 ### /c _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor