2013-01-18 At 11:33 PM
Destructuring assignment / tuple unpack in Python - by examples
Destructuring assignment (a.k.a. tuple unpack) in Python, seems to be very useful thing. The most basic variant:
»> x,y = 1,2
»> x,y
(1, 2)
what is identical to:
»> x, y = [1,2]
»> x, y = (1,2)
Any iterator would fit, e.g. class impl. __iter__ function (coroutine):
»> class test(object):
… def __iter__(self):
… for x in (1,2): yield x
»> a,b = test()
»> a,b
(1, 2)
regular function would produce the same result:
»> def test():
… for x in (1,2): yield x
Using destructuring is specially useful when function/method returns more than one result (technically, it returns only one result - tuple):
»> def f(): return 1,2
»> x,y = f()
»> x,y
(1, 2)
Although I’m working with python from the version 2.2., recently I have played around with Clojure and discovered that some advanced desctructuring features that Clojure offers, can be found in python too, e.g.:
»> x,[y,z] = 1,[2,3]
»> x, y, z
(1, 2, 3)
more complex example (note that variable “_” is 2 times assigned):
»> x,[y,z,[w,_,t,_]] = 1,[2,3,(4,5,6,7)]
»> x,y,z,w,t,_
(1, 2, 3, 4, 6, 7)
What looks very useful is that, destructuring can be used in function’s argument declaration:
»> def f(a,(b,c)):
… print a,b,c
This function expects 2 arguments, of which second one must be some iterator type with exactly two members:
»> f(1,(2,3))
1 2 3
——————————
UPDATE:It seems that python3 deprecates this feature, i.e. this doesn’t work in python 3.1:
def f(a,(b,c)): print a,b,c
Why? Read http://www.python.org/dev/peps/pep-3113/. Any alternative? They suggest using function annotations (py3+) http://www.python.org/dev/peps/pep-3107/.
——————————
Python 3.0+ offers taking rest of tuple into last variable:
»> x,y,*z = 1,2,3,4,5
»> x,y,z
(1, 2, [3, 4, 5])
more complex example - having nesting lists (python 3.0+):
»> x,[y,*z],t,*w = 1,[2,3,4],5,6,7
»> x,y,z,t,w
(1, 2, [3, 4], 5, [6, 7])
Argument unpacking naturally follows destructuring theme, which can be seen as “opposite” operation . Small example:
»> def f(a,b): print a,b
…
»> f(*[1,2])
1 2
(Note: the same could be achived with apply function until it was deprecated in python 3+).
Destructuring is common thing in other languages, e.g. javascript, ruby, php (example http://artlung.com/blog/2007/02/21/destructured-assignment-in-ruby-php-and-javascript/).
It seems that good ideas are constantly being freely “borrowed”.

:

