[Python-Dev] syntactic shortcut - unpack to variably sized list

Nick Coghlan ncoghlan at iinet.net.au
Fri Nov 19 11:29:45 CET 2004


Carlos Ribeiro wrote:
> list.pop doesn't solve the case for  when the data is stored in a
> tuple (which is immutable).

For immutable objects, you *have* to make a copy, so I don't see any real 
downside to just using:

   a, b, T = T[0],  T[1], T[2:]

While I think iunpack is kind of neat, I don't think it solves anything which is 
currently a major problem, as it is really just a different way of spelling the 
above slicing. The major portion (sans some index checking) of iunpack(T, 2) can 
be written on one line:

   a, b, T = (T[i] for i in (range(2) + [slice(2, None)]))

When the number of elements to be unpacked is known at compile time (as it has 
to be to use tuple unpacking assignment), there seems little benefit in moving 
things inside a generator instead of spelling them out as a tuple of slices.

However, the OP's original question related to a list, where the goal was to 
both read the first couple of elements *and* remove them from the list (i.e. 
'pop'ing them). This is similar to the motivating use cases which came up the 
last time the "a, b, *c = L" idea was raised.

At the moment, the main choices are to use the syntax above (and make an 
unnecessary copy), make multiple calls to list.pop (with associated function 
overhead), or call del directly after reading the slice you want (i.e. doing a 
list.pop of a slice in Python code).

According to the current docs, L.pop(i) is defined as being equivalent to:

   x = L[i]; del L[i]; return x

And Armin pointed out that setting "i = slice(<whatever>)" actually causes that 
stated equivalence to break:

 >>> L = [1, 2, 3, 4]
 >>> i = slice(2)
 >>> L.pop(i)
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
TypeError: an integer is required
 >>> L[i]
[1, 2]
 >>> del L[i]
 >>> L
[3, 4]
 >>>

So, we could either fix the docs to explicitly exclude slices from list.pop, or 
just fix the method so slices work as the argument. The latter is a little more 
work, but it does provides a nice way of spelling "read and remove" for a range 
of elements. Which is why I'm hoping one of the proponents of "a, b, *c = L" 
will be willing to provide an implementation.

Cheers,
Nick.

-- 
Nick Coghlan               |     Brisbane, Australia
Email: ncoghlan at email.com  | Mobile: +61 409 573 268


More information about the Python-Dev mailing list