variable length tuple assignment

H

Helmut Jarausch

Sorry if this is too simple but I couldn't find.

I vaguely remember there is a means to assign a variable length tuple
and catch the 'rest' like

S="a,b,c,d"

(A,B,<list of remaining items>) = S.split(',')

I know I could do
SL= split(',')
(A,B)=SL[:2]
Rest= SL[2:]

but is there some shorthand for this?

Many thanks for a hint,

Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany
 
C

Chris Rebert

Sorry if this is too simple but I couldn't find.

I vaguely remember there is a means to assign a variable length tuple
and catch the 'rest'  like

S="a,b,c,d"

(A,B,<list of remaining items>) = S.split(',')

In Python 3.0 (IIRC):

A, B, *rest = S.split(',')

Cheers,
Chris
 
T

Tim Chase

Chris said:
In Python 3.0 (IIRC):

A, B, *rest = S.split(',')

As an aside, as of the last time I read the PEP[1] on this, I
believe it exhausts (or attempts to exhaust) any iterator. IMHO,
I think this exhausting is a bad idea because it prevents things like

def numbers(start=0):
i = start
while True:
yield i
i += 1

CONST_A, CONST_B, CONST_C, *rest = numbers()

which will hang in current Py3.0 until you blow a stack or
overrun your heap somewhere because it will try to exhaust the
infinite loop. It also changes the type from iter() to list()
for the remaining content (not as grevious).


I agree that the "internal star" usage needs to exhaust the iterator:

A, *rest, C, D = s.split(',')

but the terminal-star syntax should be a little more gracious
with iterators.

Anyways, my $0.02 (minus taxes, money for multiple bailouts, and
deflated by economic conditions -- so not worth much :).

-tkc

[1]
http://www.python.org/dev/peps/pep-3132/
 
S

Steven D'Aprano

Tim said:
As an aside, as of the last time I read the PEP[1] on this, I
believe it exhausts (or attempts to exhaust) any iterator. IMHO,
I think this exhausting is a bad idea because it prevents things like

def numbers(start=0):
i = start
while True:
yield i
i += 1

CONST_A, CONST_B, CONST_C, *rest = numbers()

which will hang in current Py3.0 until you blow a stack or
overrun your heap somewhere because it will try to exhaust the
infinite loop.

But what else can it do? Do you expect Python to read your mind and
magically know when you intend to use rest and when you're intending to
just throw it away?

Perhaps Python could do that, via static analysis -- if rest is never used
again, don't bother exhausting the iterator. But that will lead to
differences in iterators that have side-effects. It will also have a subtle
difference in behaviour here:

it = xrange(5) # for example
a, b, c, *rest = it
L = list(it) # L is now [3, 4]

versus

a, b, c, *rest = xrange(5)
parrot(rest)
L = list(it) # L is now []

It also changes the type from iter() to list()
for the remaining content (not as grevious).

But that's what unpacking does. It would be a major semantic change for

x, *s = some_iterator

to make s an alias of some_iterator. And why would you want it to? If you
do, just do this:

x, s = some_iterator.next(), some_iterator
 

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

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top