When a Python list is known to always contain a single item, is there a way to access it other than:
mylist[0]
You may ask, ‘Why would you want to?’. Curiosity alone. There seems to be an alternative way to do everything in Python.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Raises exception if not exactly one item:
Sequence unpacking:
singleitem, = mylist
# Identical in behavior (byte code produced is the same),
# but arguably more readable since a lone trailing comma could be missed:
[singleitem] = mylist
Rampant insanity, unpack the input to the identity lambda function:
# The only even semi-reasonable way to retrieve a single item and raise an exception on # failure for too many, not just too few, elements as an expression, rather than a # statement, without resorting to defining/importing functions elsewhere to do the work singleitem = (lambda x: x)(*mylist)
All others silently ignore spec violation, producing first or last item:
Explicit use of iterator protocol:
singleitem = next(iter(mylist))
Destructive pop:
singleitem = mylist.pop()
Negative index:
singleitem = mylist[-1]
Set via single iteration for (because the loop variable remains available with its last value when a loop terminates):
for singleitem in mylist: break
There are many others (combining or varying bits of the above, or otherwise relying on implicit iteration), but you get the idea.
Method 2
I will add that the more_itertools
library has a tool that returns one item from an iterable.
from more_itertools import one iterable = ["foo"] one(iterable) # "foo"
In addition, more_itertools.one raises an error if the iterable is empty or has more than one item.
iterable = [] one(iterable) # ValueError: not enough values to unpack (expected 1, got 0) iterable = ["foo", "bar"] one(iterable) # ValueError: too many values to unpack (expected 1)
more_itertools is a third-party package > pip install more-itertools
Method 3
(This is an adjusted repost of my answer to a similar question related to sets.)
One way is to use reduce with lambda x: x.
from functools import reduce
> reduce(lambda x: x, [3]})
3
> reduce(lambda x: x, [1, 2, 3])
TypeError: <lambda>() takes 1 positional argument but 2 were given
> reduce(lambda x: x, [])
TypeError: reduce() of empty sequence with no initial value
Benefits:
- Fails for multiple and zero values
- Doesn’t change the original list
- Doesn’t need a new variable and can be passed as an argument
Cons: “API misuse” (see comments).
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0