Rats! vararg assignments don't work

S

samwyse

I'm a relative newbie to Python, so please bear with me. After seeing
how varargs work in parameter lists, like this:
def func(x, *arglist):
and this:
x = func(1, *moreargs)
I thought that I'd try this:
first, *rest = arglist
Needless to say, it didn't work. That leaves me with two questions.

First, is there a good way to do this? For now, I'm using this:
first, rest = arglist[0], arglist[1:]
but it leaves a bad taste in my mouth.

Second, is there any good reason why it shouldn't work? It seems like
such an obvious idiom that I can't believe that I'm the first to come up
with the idea. I don't really have the time right now to go source
diving, so I can't tell if it would be wildly inefficient to implement.

Thanks!
 
M

Matimus

Your attemtp:

Code:
first, rest = arglist[0], arglist[1:]

Is the most obvious and probably the most accepted way to do what you
are looking for. As for adding the fucntionality you first suggested,
it isn't likely to be implemented. The first step would be to write a
PEP though. Remember, in Python "there is only one way to do it". So,
unless you can come up with a valid use case where that syntax allows
you to do something that wasn't possible before, I wouldn't count on
getting much support.
 
G

George Sakkis

Your attemtp:

Code:
first, rest = arglist[0], arglist[1:]

Is the most obvious and probably the most accepted way to do what you
are looking for. As for adding the fucntionality you first suggested,
it isn't likely to be implemented. The first step would be to write a
PEP though.

The time machine did it again: http://www.python.org/dev/peps/pep-3132/.

George
 
G

Gary Herron

samwyse said:
I'm a relative newbie to Python, so please bear with me. After seeing
how varargs work in parameter lists, like this:
def func(x, *arglist):
and this:
x = func(1, *moreargs)
I thought that I'd try this:
first, *rest = arglist
Needless to say, it didn't work. That leaves me with two questions.

First, is there a good way to do this? For now, I'm using this:
first, rest = arglist[0], arglist[1:]
but it leaves a bad taste in my mouth.
Well, your moreargs parameter is a tuple, and there are innumerable ways
to process a tuple. (And even more if you convert it to a list.)

If you are just interested in extracting only the first arg, then your
code is quite Pythonic. However, if you are going to do that in a loop
to successively process each arg, the you have several better options:

For instance:
for arg in moreargs: # Loop through each arg
<do something with arg>

or

for i in range(len(moreargs)):
<do something with morergs> # Extract ith arg

or

argslist = list(moreargs)
while argslist:
firstarg = argslist.pop(0) # Extract first arg
<do something with firstarg>

Gary Herron
 
S

samwyse

Gary said:
samwyse said:
I'm a relative newbie to Python, so please bear with me. After seeing
how varargs work in parameter lists, like this:
def func(x, *arglist):
and this:
x = func(1, *moreargs)
I thought that I'd try this:
first, *rest = arglist
Needless to say, it didn't work. That leaves me with two questions.

First, is there a good way to do this? For now, I'm using this:
first, rest = arglist[0], arglist[1:]
but it leaves a bad taste in my mouth.

Well, your moreargs parameter is a tuple, and there are innumerable ways
to process a tuple. (And even more if you convert it to a list.)

My use-case is (roughtly) this:
first, *rest = f.readline().split()
return dispatch_table{first}(*rest)
 
S

samwyse

George said:
Your attemtp:

Code:
first, rest = arglist[0], arglist[1:]

Is the most obvious and probably the most accepted way to do what you
are looking for. As for adding the fucntionality you first suggested,
it isn't likely to be implemented. The first step would be to write a
PEP though.


The time machine did it again: http://www.python.org/dev/peps/pep-3132/.

Thanks! Now I just need to wait for Py3K and all of my problems will be
solved. ;-)

Actually, I'm surprised that the PEP does as much as it does. If tuples
are implemented as S-expressions, then something like this:
car, *cdr = tuple
while leaving cdr a tuple would be trivial to implement. Of course, I'm
an old-school LISPer, so what I consider surprising behavior doesn't
always surprise anyone else, and vice versa.
 
B

Bruno Desthuilliers

Matimus a écrit :
(snip)
> Remember, in Python "there is only one way to do it".

Actually, it's :
"There should be one-- and preferably only one --obvious way to do it.".

.... Which is quite different. Please notice the "should", "preferably"
and "obvious".
 
M

Maric Michaud

samwyse a écrit :
George said:
Your attemtp:

Code:
first, rest = arglist[0], arglist[1:]

Is the most obvious and probably the most accepted way to do what you
are looking for. As for adding the fucntionality you first suggested,
it isn't likely to be implemented. The first step would be to write a
PEP though.

The time machine did it again: http://www.python.org/dev/peps/pep-3132/.

Thanks! Now I just need to wait for Py3K and all of my problems will be
solved. ;-)

Actually, I'm surprised that the PEP does as much as it does. If tuples
are implemented as S-expressions, then something like this:
car, *cdr = tuple
while leaving cdr a tuple would be trivial to implement. Of course, I'm
an old-school LISPer, so what I consider surprising behavior doesn't
always surprise anyone else, and vice versa.

Remember all these are copies of the original sequence, the lisp
equivalent to car/cdr is feasible with an iterator :

it = iter(seq)
car, cdr = it.next(), it
 
S

Sion Arrowsmith

samwyse said:
[ ... ]
My use-case is (roughtly) this:
first, *rest = f.readline().split()
return dispatch_table{first}(*rest)

first, rest = f.readline().split(None, 1)
return dispatch_table{first}(*rest.split())
 
A

Alex Martelli

samwyse said:
Actually, I'm surprised that the PEP does as much as it does. If tuples
are implemented as S-expressions, then something like this:

Tuples are implemented as compact arrays of pointer-to-PyObject (so are
lists, BTW). So, for example, a 10-items tuple takes 40 bytes (plus a
small overhead for the header) on a 32-bit build, not 80 as it would if
implemented as a linked list of (pointer-to-object, pointer-to-next)
pairs; addressing sometuple[N] is O(1), NOT O(N); etc, etc.


Alex
 
S

samwyse

samwyse said:
samwysewrote:
I thought that I'd try this:
first, *rest = arglist
Needless to say, it didn't work.
[ ... ]
My use-case is (roughtly) this:
first, *rest = f.readline().split()
return dispatch_table{first}(*rest)

first, rest = f.readline().split(None, 1)
return dispatch_table{first}(*rest.split())

Hey, I like that! Thanks!
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top