Karim.C
Karim.C

Reputation: 21

Filter list within list to get all second numbers

Im trying to filter the following list:

filtered = [[1.0, 3.0], [2.0, 70.0], [40.0, 3.0], [5.0, 50.0], [6.0, 5.0], [7.0, 21.0]]

To get every second number in the list within list, resulting in the following:

filtered = [[3.0], [70.0], [3.0], [50.0], [5.0], [21.0]]

I tried the following which does not work:

from operator import itemgetter
a = map(itemgetter(0), filtered)
print(a)

The following also doesn't work:

from operator import itemgetter
b = map(filtered,key=itemgetter(1))[1]
print(b)

In the last line of code i have shown, if I change map to max, it does find the largest value of all the second floats in the lists. So i assume that i am close to a solution?

Upvotes: 1

Views: 141

Answers (2)

abarnert
abarnert

Reputation: 365657

You are not closer to a solution trying to pass a key to map. map only takes a function and an iterable (or multiple iterables). Key functions are for ordering-related functions (sorted, max, etc.)

But you were actually pretty close to a solution in the start:

a = map(itemgetter(0), filtered)

The first problem is that you want the second item (item 1), but you're passing 0 instead of 1 to itemgetter. That obviously won't work.

The second problem is that a is a map object—a lazily iterable. It does in fact have the information you want:

>>> a = map(itemgetter(1), filtered)
>>> for val in a: print(val, sep=' ')
3.0 70.0 3.0 50.0 5.0 21.0

… but not as a list. If you want a list, you have to call list on it:

>>> a = list(map(itemgetter(1), filtered))
>>> print(a)
[3.0, 70.0, 3.0, 50.0, 5.0, 21.0]

Finally, you wanted a list of single-element lists, not a list of elements. In other words, you want the equivalent of item[1:] or [item[1]], not just item[1]. You can do that with itemgetter, but it's a pretty ugly, because you can't use slice syntax like [1:] directly, you have to manually construct the slice object:

>>> a = list(map(itemgetter(slice(1, None)), filtered))
>>> print(a)
[[3.0], [70.0], [3.0], [50.0], [5.0], [21.0]]

You could write this a lot more nicely by using a lambda function:

>>> a = list(map(lambda item: item[1:], filtered))
>>> print(a)
[[3.0], [70.0], [3.0], [50.0], [5.0], [21.0]]

But at this point, it's worth taking a step back: map does the same thing as a generator expression, but map takes a function, while a genexpr takes an expression. We already know exactly what expression we want here; the hard part was turning it into a function:

>>> a = list(item[1:] for item in filtered)
>>> print(a)

Plus, you don't need that extra step to turn it into a list with a genexpr; just swap the parentheses with brackets and you've got a list comprehension:

>>> a = [item[1:] for item in filtered]
>>> print(a)

Upvotes: 0

jspcal
jspcal

Reputation: 51894

You can use a list comprehension.

x = [[el[1]] for el in filtered]

or:

x = [[y] for x,y in filtered]

You can also use map with itemgetter. To print it, iterate over the iterable object returned by map. You can use list for instance.

from operator import itemgetter
x = map(itemgetter(1), filtered)
print(list(x))

Upvotes: 1

Related Questions