Reputation: 83
I would like to fetch i'th element from all the sub lists in a list of lists.I tried using map and lambda function as below
extract = lambda x,i :x[i]
a = [[1,2,3],[4,5,6],[6,7,8]]
b = list(map(extract(i = 1),a))
I expect b to be [2,5,7] but I know the last line doesn't work. How should I approach this with map and lambda
Upvotes: 2
Views: 324
Reputation: 10614
You do not need to hard code the index.
IMHO, you should return a lambda function from extract
method by doing something like this perhaps:
def extract(i):
return lambda x : x[i]
a = [[1,2,3],[4,5,6],[6,7,8]]
b = list(map(extract(1), a))
print(b)
Output:
[2, 5, 7]
Note: Better(read pythonic) approach will be to use list comprehension like this:
a = [[1,2,3],[4,5,6],[6,7,8]]
b = [li[1] for li in a]
print(b)
Upvotes: 1
Reputation: 54
I also vote for the 'for' solution. Functional programming syntax looks beautiful but its too much overhead sometimes.
a = [[1,2,3],[4,5,6],[6,7,8]]
b = list(map(lambda x: x[1], a)) # Brr, how many types conversions involved
c = [x[1] for x in a] # Looks more lightweight
Lets just check:
import timeit
timeit.timeit('a = [[1,2,3],[4,5,6],[6,7,8]]; b = [x[1] for x in a]', number=10000)
> 0.01244497299194336
timeit.timeit('a = [[1,2,3],[4,5,6],[6,7,8]]; b = list(map(lambda x: x[1], a))', number=10000)
> 0.021031856536865234
2 times slower.
Upvotes: 0
Reputation: 26315
I would suggest using operator.itemgetter
here to fetch the second item of each sublist:
from operator import itemgetter
a = [[1,2,3],[4,5,6],[6,7,8]]
print(list(map(itemgetter(1), a)))
# [2, 5, 7]
Or using lambda
:
a = [[1,2,3],[4,5,6],[6,7,8]]
print(list(map(lambda x: x[1], a)))
# [2, 5, 7]
Your anonymous function:
extract = lambda x,i :x[i]
Needs to instead map specifically an index:
extract = lambda x: x[1]
Then you can simply map this function to your list with map(extract(1), a)
.
Upvotes: 1
Reputation: 164693
The underlying problem is your first function argument needs to be specified when you call extract
. This is possible via functools.partial
:
from functools import partial
b = list(map(partial(extract, i=1), a)) # [2, 5, 7]
But this is relatively inefficient, since a new function is created for each iteration of a
. Instead, as others have advised, use operator.itemgetter
:
from operator import itemgetter
b = list(map(itemgetter(1), a)) # [2, 5, 7]
As an aside, PEP 8 advises against naming lambda
functions; define explicitly instead:
def extract(x, i):
return x[i]
Upvotes: 2
Reputation: 16603
You can hard code in the 1
:
extract = lambda x: x[1]
a = [[1,2,3],[4,5,6],[6,7,8]]
b = list(map(extract,a))
print(b)
# [2, 5, 7]
You normally don't want to store a lambda
to a variable, this is better:
def extract(x):
return x[1]
b = list(map(extract, a))
Or simply this:
b = list(map(lambda x: x[1], a))
You can also use a list comprehension, which I personally think is the best option:
c = [x[1] for x in a]
print(b == c)
True
Upvotes: 2