Giacomo d'Antonio
Giacomo d'Antonio

Reputation: 2275

Head and tail in one line

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]

Upvotes: 119

Views: 153874

Answers (5)

Gareth Latty
Gareth Latty

Reputation: 89087

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:]

Upvotes: 247

ABridgeTooFar
ABridgeTooFar

Reputation: 21

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]

Upvotes: 2

Nikolay Fominyh
Nikolay Fominyh

Reputation: 9256

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.

Upvotes: 14

BobIsNotMyName
BobIsNotMyName

Reputation: 425

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]

Upvotes: 3

fraxel
fraxel

Reputation: 35309

>>> 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]

Upvotes: 40

Related Questions