116

Is there a pythonic way to unpack a list in the first element and the "tail" in a single command?

For example:

>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
Georgy
  • 12,464
  • 7
  • 65
  • 73
Giacomo d'Antonio
  • 2,215
  • 3
  • 19
  • 23
  • 10
    Remember that lists are not implemented as singly-linked lists in Python, so this operation is costly (as in: the whole list needs to be copied). Depending on what you want to achieve, this might or might not be a problem. I am just mentioning that because this type of list destructuring is often found in functional languages, where it is actually a very cheap operation. – Niklas B. May 13 '12 at 23:49

5 Answers5

241

Under Python 3.x, you can do this nicely:

>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

A new feature in 3.x is to use the * operator in unpacking, to mean any extra values. It is described in PEP 3132 - Extended Iterable Unpacking. This also has the advantage of working on any iterable, not just sequences.

It's also really readable.

As described in the PEP, if you want to do the equivalent under 2.x (without potentially making a temporary list), you have to do this:

it = iter(iterable)
head, tail = next(it), list(it)

As noted in the comments, this also provides an opportunity to get a default value for head rather than throwing an exception. If you want this behaviour, next() takes an optional second argument with a default value, so next(it, None) would give you None if there was no head element.

Naturally, if you are working on a list, the easiest way without the 3.x syntax is:

head, tail = seq[0], seq[1:]
Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
  • 1
    sorry, I used the term tail unproperly. I mean what I say in the example, that is the list without the first element – Giacomo d'Antonio May 10 '12 at 10:55
  • @Giacomod'Antonio My mistake, I didn't read closely enough. What you said is the normal meaning of tail. Actually, that makes it even simpler. – Gareth Latty May 10 '12 at 10:56
  • Can you update a little about complexity of `head, tail = seq[0], seq[1:]` vs `head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]`. 2nd option still has O(N) complexity, instead of O(1)? – Nikolay Fominyh Oct 03 '16 at 18:17
  • 1
    @NikolayFominyh They are both the same - they both take the head element and construct a new list containing the tail elements. No difference in complexity. Another class could implement `__getitem__`/`__setitem__` to do the tail operation lazily, but the built-in list does not. – Gareth Latty Jul 04 '17 at 01:25
  • 2
    On a list of 800 elements doing it 1M times, I have 2.8s for the head, *tail = seq solution and only 1.8s for head, tail = seq[0], seq[1:] solution. Slicing is still faster for lists. – Cabu Oct 18 '17 at 13:45
  • What's the performance of this? Are python lists capable of doing O(1) head, tail? – CMCDragonkai Mar 22 '18 at 04:38
  • 2
    @CMCDragonkai No, Python's main list class is an array list. This would be O(n) as it involves copying the tail to a new list (with one O(1) get for the head). – Gareth Latty Mar 22 '18 at 08:05
  • 1
    This nice syntax is another reason to move to `python 3.x` – daparic Dec 14 '18 at 14:47
  • If `seq` is empty, a `ValueError: not enough values to unpack (expected at least 1, got 0)` exception is thrown. Is there a way to have `head` assigned `None` in this case (other than catching the exception, of course)? – Simone Jun 28 '19 at 15:44
  • 1
    @Simone Only if you fall back to the method I gave for 2.x - `next()` takes a second argument which is a default value, so `next(it, None)` would do what you want. Catching the exception as you describe would probably be the simplest choice. Obviously you could also check for length first if you were working with a list or something, but this does introduce a potential race condition and requires a known length (which isn't true of an arbitrary iterable). – Gareth Latty Jun 28 '19 at 15:58
  • 1
    Love this answer, thanks. You can also unpack more items before reaching for the *rest: `nums = [1, 2, 3, 4]` `head, neck, *tail = nums` `# head == 1` `# neck == 2` `# tail = [3, 4, 5, 6, 7]` – avlnx Sep 08 '20 at 15:05
40
>>> mylist = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head, tail = mylist[0], mylist[1:]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
fraxel
  • 34,470
  • 11
  • 98
  • 102
11

For O(1) complexity of head,tail operation you should use deque however.

Following way:

from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l

It's useful when you must iterate through all elements of the list. For example in naive merging 2 partitions in merge sort.

Nikolay Fominyh
  • 8,946
  • 8
  • 66
  • 102
  • 1
    It seems like deque(list_instance) has O(N) complexity. Am i wrong? – Никита Конин Jun 08 '17 at 16:30
  • 1
    @НикитаКонин, you are right about construction of deque. However, if you want to access first element more than once, then `head, tail = l.popleft(), l` is ~O(1). `head, tail = seq[0], seq[1:]` is O(n). – Nikolay Fominyh Jun 14 '17 at 16:23
  • It looks like you can just do `head = l.popleft()` and `tail` is just an alias for `l`. If `l` changes `tail` changes too. – kon psych Feb 24 '20 at 19:47
3

Python 2, using lambda

>>> head, tail = (lambda lst: (lst[0], lst[1:]))([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
BobIsNotMyName
  • 415
  • 4
  • 11
  • 2
    why in the world would you do this instead of just `head, tail = lst[0], lst[1:]`? if OP means to use a literal then he could split head and tail manually `head, tail = 1, [1, 2, 3, 5, 8, 13, 21, 34, 55]` – Filipe Pina Mar 29 '18 at 16:26
  • 3
    (1) Op's question was whether it's possible to do this in one line (so no `lst = ...` in previous line). (2) Doing `head, tail = lst[0], lst[1:]` leaves the code open to side-effects (consider `head, tail = get_list()[0], get_list()[1:]`), and is different than Op's form `head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]`. – BobIsNotMyName Mar 30 '18 at 01:02
  • That being said, I acknowledge that this is a bad obfuscated way to get the head/tail. But I thought it was the best answer for Python 2 for Op's specific question. – BobIsNotMyName Mar 30 '18 at 01:03
2

Building on the Python 2 solution from @GarethLatty, the following is a way to get a single line equivalent without intermediate variables in Python 2.

t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]

If you need it to be exception-proof (i.e. supporting empty list), then add:

t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]

If you want to do it without the semicolon, use:

h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140