5 ms·
Python insights
- DaniFong 18y agoHere's one I only found out about recently. 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.
- qwph 18y agoInteresting. It seems that (according to my Python prompt) 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?
- DaniFong 18y agoI don't know if there are any higher level differences, but I suspect the pure tuple version (the first) would be a little faster. Edit: Nope! Up to randomness due to multitasking and paging, a benchmark on one million cases yields the same times, up to noise.
- scott_s 18y agoThe last is different in that it returns a list, not a tuple. This makes a difference if you want to change the object. >>> 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]
- qwph 18y agoAha! There's actually no difference (i think) between: 1, 2 and: (1, 2) That seems to make sense.
- scott_s 18y agoI think that is true, but I think that it's only later versions of Python (2.5+, maybe?) that allow you to omit the parenthesis. I've had earlier versions (2.3?) complain of a syntax error when I leave them out.
- DaniFong 18y agoIncidentally, this functionality is but a subset of Erlang/Haskell style pattern matching, which does seem to be very helpful in many circumstances (unlike, as is rumored, at least by PG, prolog's pattern matching). It's actually a favorite feature of mine: one that I'd like to put into any language I'd settle into.
- olavk 18y agoProlog-style pattern matching is quite helpful, at least in Prolog :) I think Haskell-style might be a subset of Prolog-style. 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)
- newt0311 18y agobe wary of tuple unpacking inside function headers. PEP 3113 removes it from python 3000. See http://www.python.org/dev/peps/pep-3113/ http://www.python.org/dev/peps/pep-3113/ for more details.
- DaniFong 18y agoWhat?! Why is Python 3000 consistently removing all the cool stuff?!
- jauco 18y agohttp://www.python.org/dev/peps/pep-3113/#why-they-should-go http://www.python.org/dev/peps/pep-3113/#why-they-should-go
- DaniFong 18y agoStrange. 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...
- kcl 18y agoq)10+1 2 3 11 12 13
- newt0311 18y agoNo. I have to say, I agree with the BDFL here. Tuple unpacking in function headers is prone to bugs and can lead to ambiguous behaviour. It 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.
- BrandonM 18y agoFrom the article: 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?
- schtog 18y agoThere is a list-reverse that changes the list and returns None but maybe the reason there isn't one for strings are because they are immutable while lists are mutable.
- BrandonM 18y agoThat's a good point. I was thinking more along the lines, though, that there are some times where you actually need to reverse a list. How often does it make sense to reverse a string? When palindrome testing?