What's the most pythonic way to take the single item of a 1-sized list in python?
I usually go for
item = singlet_list[0]
This would fail for an empty list, but I would like a way to make it fail even if the list is longer, something like:
assert(len(singlet_list) == 1)
item = singlet_list[0]
but I find this ugly. Is there anything better?
This blog post suggests an elegant solution I fell in love with:
(item,) = singlet_list
I find it much more readable, and plus it works with any iterable, even if it is not indexable.
EDIT: Let me dig a little more
This construct is called sequence unpacking or multiple assignment throughout the python documentation, but here I'm using a 1-sized tuple on the left of the assignment.
This has actually a behaviour that is similar to the 2-lines in the initial question: if the list/iterable singlet_list
is of length 1, it will assign its only element to item
. Otherways, it will fail with an appropriate ValueError
(rather than an AssertionError
as in the question's 2-liner):
>>> (item,) = [1]
>>> item
1
>>> (item,) = [1, 2]
ValueError: too many values to unpack
>>> (item,) = []
ValueError: need more than 0 values to unpack
As pointed out in the blog post, this has some advantages:
[0]
indexing, and it doesn't pass unobserved even in complex statements.assert
You could use an inline if...else
and define a default value like this:
If singlet_list
contains one or more values:
singlet_list = [2]
item = singlet_list[0] if singlet_list else False
print item
output:
2
If singlet_list
is empty:
singlet_list = []
item = singlet_list[0] if singlet_list else False
print item
output:
False
This uses the fact that an empty list evaluates to False
.
Similarly, if you would like a default value to be assigned if the list doesn't contain exactly one element, you could check the length:
item = singlet_list[0] if len(singlet_list) == 1 else False
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With