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
# Not a fan of this one, as the comma still feels missable but the parentheses do
# draw attention (they're completely superfluous), so it's less likely to be missed
# Still 100% identical in behavior, with identical byte code
(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 for too many items, 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.
Answer from ShadowRanger on Stack OverflowRaises 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
# Not a fan of this one, as the comma still feels missable but the parentheses do
# draw attention (they're completely superfluous), so it's less likely to be missed
# Still 100% identical in behavior, with identical byte code
(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 for too many items, 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.
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
How can I read 1 value from a list in python? - Stack Overflow
python - Pythonic way to get the single element of a 1-sized list - Stack Overflow
python select specific elements from a list - Stack Overflow
How to access List elements in Python - Stack Overflow
What is the fastest way to get one element from a Python list?
Does slicing a Python list change the original list?
How do I extract elements from several lists at the same time?
Read a specific item in index i:
item = L[index]
Read a sequence of items from index 'start' to index 'stop':
seq = L[start:stop]
Iterate over a list:
for item in L:
print item
If you need both the index and the item, use the enumerate function:
for index, item in enumerate(L):
print index, item
You can also get the reversed list:
L.reverse()
Get list length:
length = len(L)
And there are so much more operations you can perform on lists.
You can just do list[i] , i being the index of the element to be read.
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:
- This will not to fail silently, as required by the original question.
- It is much more readable than the
[0]indexing, and it doesn't pass unobserved even in complex statements. - It works for any iterable object.
- (Of course) it uses only one line, with respect to explicitly using
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
Using a list comprehension
line = '0,1,2,3,4,5,6,7,8,9,10'
lst = line.split(',')
one, four, ten = [lst[i] for i in [1,4,10]]
I think you are looking for operator.itemgetter:
import operator
line=','.join(map(str,range(11)))
print(line)
# 0,1,2,3,4,5,6,7,8,9,10
alist=line.split(',')
print(alist)
# ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
one,four,ten=operator.itemgetter(1,4,10)(alist)
print(one,four,ten)
# ('1', '4', '10')
I'd start by not calling it list, since that's the name of the constructor for Python's built in list type.
But once you've renamed it to cities or something, you'd do:
print(cities[0][0], cities[1][0])
print(cities[0][1], cities[1][1])
It's simple
y = [['vegas','London'],['US','UK']]
for x in y:
for a in x:
print(a)