Python insights
eli.thegreenplace.net
eli.thegreenplace.net
Multiple assignment in Python is already well known.
x, y = 10, 50
But this also works when the left or right variable lists are sequences. [x,y] = 10,4
t = (1,2,3)
a,b,c = t
If you have a loop or a comprehension, and the values are sequences, you can access them like so for (left, right) in zip(leftArray,rightArray):
...
You can also do variable assignment inside an argument list. To see what I mean, suppose you're writing a 2d geometry library, and you use tuples as points. Ordinarily you might write def func(point):
x, y = point[0], point[1]
...
or even def func(point):
x, y = point
...
Instead, you can just write def func((x,y)):
...
This has many advantages. It gets around the problem of having to navigate to some other place to find out what composite data structures are. Points are just (x,y) tuples. It makes it easier to write sensible names, in many cases, which is crucial in a dynamic language. It's shorter. You spend less time packing, unpacking, and generally, schlepping your data, and more time actually doing things.Unfortunately, it's not the most generic of methods. It fixes you to a particular data representation. This is effective in certain cases, but is otherwise a problem when you need to change things. In practice, though, this can be avoided, and other code would break during such changes too.
Python-style is destructuring without pattern-matching, so its not really the same. The assignment will be executed whether the structures match or not - if they don't match (e.g. the right hand value is not a list or does not have the right size) an exception is raised.
Pattern matching would not be that useful in Python anyway I suppose (unless you program Python as if it was Haskell)
x, y = 1, 2
and [x, y] = 1, 2
and even x, y = [1, 2]
are all identical in function. Are there any (subtle) distinctions between the three? >>> tuple = x, y = 1, 2
>>> type(tuple)
<type 'tuple'>
>>> tuple
(1, 2)
>>> tuple[0] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> lst = x, y = [1, 2]
>>> type(lst)
<type 'list'>
>>> lst
[1, 2]
>>> lst[0] = 3
>>> lst
[3, 2]1, 2
and:
(1, 2)
That seems to make sense.
Edit:
Nope! Up to randomness due to multitasking and paging, a benchmark on one million cases yields the same times, up to noise.
Why is Python 3000 consistently removing all the cool stuff?!
I'm going to have to disagree with the BFDL here. Tuple parameters are probably not used much because people don't know about them, not because they're unhelpful. And all the code transformations he shows below end up longer. And they don't seem to be any easier to read. :-/
Consider what PG says in the arc tutorial.
"Since functions of one argument are so often used in Lisp programs, Arc has a special notation for them. [... _ ...] is an abbreviation for (fn (_) (... _ ...)). So our first map example could have been written
arc> (map [+ _ 10] '(1 2 3))
(11 12 13)
Removing variables is a particularly good way to make programs shorter. An unnecessary variable increases the conceptual load of a program by more than just what it adds to the length."It's strange that this would be what pushes me over the fence, but I think Python and I are going to end up parting ways...
q)10+1 2 3
11 12 13It also doesn't fit very well with other features like keyword arguments.
You are right that the extra variable leads to extra mental overhead but so does potential ambiguous behavior.
String reverse
Python doesn’t have a built-in reverse method for strings. Luckily, this can be easily done with slices:
def reverse(str):
return str[::-1]
If you don't like str[::-1] (even though it is a common idiom), you could just use
"".join(reversed(str))
Is reversing a string really common enough to have a special function for it with such a general name like reverse?