list1 = [((100,3),3,5,6),((200,3),3,5,6),((300,3),3,5,6),((400,3),3,5,6)]
I want to get first element of each tuple of tuples from the list.
I can achieve it easily using loop:
for i in list1:
print(i[0][0])
But can for loop be avoided?
list1 = [((100,3),3,5,6),((200,3),3,5,6),((300,3),3,5,6),((400,3),3,5,6)]
I want to get first element of each tuple of tuples from the list.
I can achieve it easily using loop:
for i in list1:
print(i[0][0])
But can for loop be avoided?
List comprehension, really same as loop.
[i[0][0] for i in list1]
Or, you can use pandas.
import pandas as pd
pd.Series(list1).str[0].str[0]
Run %%timeit on all the suggested methods here and this is the faster than most suggestions except one
with numpy it gave:
31.6 µs ± 1.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
with pandas it gave:
475 µs ± 20.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
with regex the result is:
8.67 µs ± 50.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
with list comparison:
837 ns ± 8.81 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
A rather different and a faster way can be:
list1 = [((100,3),3,5,6),((200,3),3,5,6),((300,3),3,5,6),((400,3),3,5,6)]
list1=str(list1)
import re
d=re.findall("(?:\(\()(\d+)",list1)
[int(x) for x in d]
Output
[100, 200, 300, 400]
d is not definedA list comprehension is likely what you need. But for reference you can use next with an iterator, or operator.itemgetter for a functional solution:
from operator import itemgetter
def first_lazy(x): return map(itemgetter(0), x)
def first(x): return next(zip(*x))
%timeit [i[0][0] for i in list1] # 44.9 ms
%timeit list(first_lazy(first_lazy(list1))) # 68.6 ms
%timeit first(first(list1)) # 78.9 ms
Enjoy next(zip(*next(zip(*list1)))) :)
P.S.: here is some explanation.
First of all, I assume that you are using Python 3, so zip returns a generator-object, and thus subsequent calls to next are valid. So in order to group together the first entries (i.e. 2-element tuples) of each tuple in list1, we use next(zip(*list1)). In Python 2 you could do either zip(*list1)[0] or even next(iter(zip(*list1))), since zip returns a list. Note that zip expects several iterable objects as input, so we are using * to pass each entry of list1 (i.e. a 5-element tuple) as a separate argument to zip, so basically zip(*list1) means the same as
zip( ((100,3),3,5,6), ((200,3),3,5,6), ((300,3),3,5,6), ((400,3),3,5,6) )
Anyway, both in Python 3 and Python 2 the output after the first step will be the following:
((100, 3), (200, 3), (300, 3), (400, 3))
So now we have to group together the first entries of each tuple in the resulting sequence. Sounds familiar, doesn't it? Exactly, we already did it in the first step! So after applying next(zip(*)) again, we will obtain the final answer:
(100, 200, 300, 400)