У меня есть список значений, которые мне нужно отфильтровать по значениям в списке логических значений:
list_a = [1, 2, 4, 6]
filter = [True, False, True, False]
Я создаю новый отфильтрованный список со следующей строкой:
filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]
что приводит к:
print filtered_list
[1,4]
Линия работает, но выглядит (для меня) немного излишне, и мне было интересно, есть ли более простой способ добиться того же.
Советы
Резюме двух хороших советов, приведенных в ответах ниже:
1- Не называйте список filter
, как я сделал , потому что это встроенная функция.
2- Не сравнивайте вещи с тем, True
что делал я, if filter[idx]==True..
потому что в этом нет необходимости. Достаточно просто использовать if filter[idx]
.
if filter[indx] == True
Do ли не использовать ,==
если вы хотите , чтобы проверить идентичность сTrue
, использованиемis
. В любом случае в этом случае все сравнение бесполезно, вы можете просто использоватьif filter[indx]
. И наконец: никогда не используйте имя встроенного в качестве имени переменной / модуля (я имею в виду имяfilter
). Используя что-то вродеincluded
, чтобыif
хорошо читалось (if included[indx]
).Ответы:
Вы ищете
itertools.compress
:Сравнение времени (py3.x):
Не используйте
filter
в качестве имени переменной, это встроенная функция.источник
[2, 6]
?list(compress(list_a, [not i for i in fill]))
должен вернуться[2, 6]
Вот так:
Используя
zip
это вещий способ параллельного перебора нескольких последовательностей без необходимости индексации. Это предполагает, что обе последовательности имеют одинаковую длину (почтовый индекс останавливается после того, как истекает самый короткий). Использованиеitertools
для такого простого случая немного излишне ...Одна вещь, которую вы делаете в своем примере, вам действительно стоит прекратить, - это сравнивать вещи с True, обычно в этом нет необходимости. Вместо этого
if filter[idx]==True: ...
вы можете просто написатьif filter[idx]: ...
.источник
С numpy:
или см. ответ Алекса Сатмари, если list_a может быть массивом numpy, но не фильтром
Numpy обычно дает вам большой прирост скорости
источник
NumPy
более ,list
где это возможно. Но если вамlist
все равно нужно использовать , вы должны (используяNumPy
решение) создатьnp.array
из обоих списков, использовать логическую индексацию и, наконец, преобразовать массив обратно в список с помощьюtolist()
метода. Чтобы быть точным, вы должны включить создание этих объектов в сравнение по времени. Тогда использованиеitertools.compress
будет по-прежнему самым быстрым решением.Для этого используйте numpy, то есть если у вас есть массив
a
, вместоlist_a
:источник
where
.источник
С помощью python 3 вы можете использовать
list_a[filter]
для полученияTrue
значений. Чтобы получитьFalse
значения, используйтеlist_a[~filter]
источник