unpacking with default values

M

McA

Hi all,

probably a dumb question, but I didn't find something elegant for my
problem so far.
In perl you can unpack the element of a list to variables similar as
in python
(a, b, c = [0, 1, 2]), but the number of variables need not to fit the
number
of list elements.
That means, if you have less list elements variables are filled with
'undef' (None in python), if you have more list elements as necessary
the rest is ignored.

How can I achieve this behaviour with python in an elegant and fast
way?

Best regards
Andreas Mock
 
G

Gary Herron

McA said:
Hi all,

probably a dumb question, but I didn't find something elegant for my
problem so far.
In perl you can unpack the element of a list to variables similar as
in python
(a, b, c = [0, 1, 2]), but the number of variables need not to fit the
number
of list elements.
That means, if you have less list elements variables are filled with
'undef' (None in python), if you have more list elements as necessary
the rest is ignored.

How can I achieve this behaviour with python in an elegant and fast
way?

Best regards
Andreas Mock

Python 3.0 has something a bit like this. Excess values can be bound
(as a list) to the last variable:

a,b,*c = [1,2,3,4,5]

will result in c containing [3,4,5].

In Python 2.x, you can't do that directly, but you should be able to
create a function that lengthens or shortens an input tuple of arguments
to the correct length so you can do:

a,c,b = fix(1,2)
d,e,f = fix(1,2,3,4)

However, the function won't know the length of the left hand side
sequence, so it will have to be passed in as an extra parameter or hard
coded.


Gary Herron
 
M

McA

In Python 2.x, you can't do that directly, but you should be able to
create a function that lengthens or shortens an input tuple of arguments
to the correct length so you can do:

a,c,b = fix(1,2)
d,e,f = fix(1,2,3,4)

However, the function won't know the length of the left hand side
sequence, so it will have to be passed in as an extra parameter or hard
coded.

Hi Gary,

thank you for the answer.
Do you know the "protocol" used by python while unpacking?
Is it a direct assingnment? Or iterating?

Best regards
Andreas Mock
 
G

Gary Herron

McA said:
Hi Gary,

thank you for the answer.
Do you know the "protocol" used by python while unpacking?
Is it a direct assingnment? Or iterating?

Both I think, but what do you mean by *direct* assignment?
Best regards
Andreas Mock

It RHS of such an assignment can be any iterable (I think). Lets test:
(The nice thing about an interactive Python session, it that it's really
easy to test.)

>>> L = [1,2,3]
>>> a,b,c=L
>>> a,b=L
Traceback (most recent call last):
Traceback (most recent call last):
>>> G = (f for f in [1,2,3]) # A generator expression
>>> a,b,c = G
>>> G = (f for f in [1,2,3]) # A generator expression
>>> a,b = G
Traceback (most recent call last):
File said:
>>> G = (f for f in [1,2,3]) # A generator expression
>>> a,b,c,d = G
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 3 values to unpack


I'd call that direct assignment with values supplied by any iterable.

Gary Herron
 
T

Terry Reedy

McA said:
Do you know the "protocol" used by python while unpacking?
Is it a direct assingnment? Or iterating?

In CPython, at least, both, just as with normal unpack and multiple
assignment. The iterable is unpacked into pieces by iterating (with
knowledge of the number of targets and which is the catchall). The
targets are then directly bound.
1 0 LOAD_NAME 0 (range)
3 LOAD_CONST 0 (3)
6 CALL_FUNCTION 1
9 UNPACK_SEQUENCE 3
12 STORE_NAME 1 (a)
15 STORE_NAME 2 (b)
18 STORE_NAME 3 (c)
21 LOAD_CONST 1 (None)
24 RETURN_VALUE
# now starred assignment 1 0 LOAD_NAME 0 (range)
3 LOAD_CONST 0 (3)
6 CALL_FUNCTION 1
9 UNPACK_EX 2
12 STORE_NAME 1 (a)
15 STORE_NAME 2 (b)
18 STORE_NAME 3 (c)
21 LOAD_CONST 1 (None)
24 RETURN_VALUE

The only difference is UNPACK_EX (tended) instead of UNPACK_SEQUENCE.
Tne UNPACK_EX code is not yet in the dis module documentation.
But a little reverse engineering reveals the parameter meaning:
a,*b,c and *a,b,c give parameters 257 and 512 instead of 2.
Separating 2,257,512 into bytes gives 0,2; 1,1; 2,0.
a,*b and *a,b give 1, 256 or 0,1; 1,0. The two bytes
are the number of targets after and before the starred target.

Terry Jan Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,130
Latest member
MitchellTe
Top