rossbot rossbot - 5 months ago 9
Python Question

Test type of value in list during list comprehension BEFORE iterating on value?

I have a list that looks like this:

test = [[1,11],[2,22],3.0]


and I want to create a list of the first value in each pair from it like this:

[f for [f,l] in test]


so that I get this result:

[1,2]


but, as expected, I get this error:

TypeError: 'float' object is not iterable


So I tried to modify it like this:

[f for [f,l] in test if type([f,l]) != float]


and I still get the same error:

TypeError: 'float' object is not iterable


How do I test the type of the value in the list inside the list comprehension before it iterates over the items inside?

Answer

You can't do the unpacking quite so early in this case since you need the full item in order to check it's type.

>>> test = [[1,11],[2,22],3.0]
>>> [item[0] for item in test if isinstance(item, list)]
[1, 2]

The way that you were doing it (for a, b in iterable) tries the unpacking before you have a chance to look at the type so you can end up with TypeError before you have a chance to look at the items.

If you really like the unpacking as you go, you can filter the test itesm first and then write your list comprehension on the filtered data...

>>> test_iterables = (item for item in test if isinstance(item, list))
>>> [f for f, l in test_iterables]

Also note that depending on what types you want to support, it might be better to do
isinstance(item, collections.Sequence) or isinstance(item, collections.Iterable)

Comments