Проверьте тип значения в списке во время понимания списка ДО итерации по значению?
У меня есть список, который выглядит так:
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)))