Проверьте тип значения в списке во время понимания списка ДО итерации по значению?

У меня есть список, который выглядит так:

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

и я хочу создать список первого значения в каждой паре из него следующим образом:

[f for [f,l] in test]

так что я получаю этот результат:

[1,2]

но, как и ожидалось, я получаю эту ошибку:

TypeError: 'float' object is not iterable

Поэтому я попытался изменить это так:

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

и я все еще получаю ту же ошибку:

TypeError: 'float' object is not iterable

Как проверить тип значения в списке внутри списка, прежде чем он будет перебирать элементы внутри?

4 ответа

Решение

В этом случае распаковку сделать нельзя так рано, так как вам нужен полный элемент, чтобы проверить его тип.

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

То, как вы это делали (for a, b in iterable) пытается распаковать, прежде чем у вас есть возможность посмотреть на тип, чтобы вы могли в конечном итоге TypeError прежде чем у вас есть возможность посмотреть на предметы.

Если вам действительно нравится распаковка, вы можете сначала отфильтровать тестовый код, а затем записать свое понимание списка на отфильтрованных данных...

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

Также обратите внимание, что в зависимости от того, какие типы вы хотите поддерживать, может быть лучше сделать
isinstance(item, collections.Sequence) или же isinstance(item, collections.Iterable)

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

print([f for [f,l] in filter(lambda x: type(x) is list, test)])

[1, 2]

Ваша распаковка не работает, потому что ваш список содержит несоответствующие типы. Вы можете просто отфильтровать hasattr учитывая, что только ваши списки (в данном случае) будут иметь атрибут __len__ и индексировать первый элемент списка:

>>> test = [[1,11],[2,22],3.0]
>>> [i[0] for i in test if hasattr(i, '__len__')]
[1, 2]

Вы можете попробовать простой подход, как это:

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

test_copy = test[:]

for num in test:
    if type(num) != list:
        test_copy.remove(num)
else:
    print([num[0] for num in test_copy])

Выход:

[1, 2]

Вы также можете заменить последнюю строку этим, если хотите:

print(list(map(lambda x: x[0], test_copy)))
Другие вопросы по тегам