У меня есть несколько списков, содержащих одинаковое количество записей (каждый из которых указывает свойство объекта):
property_a = [545., 656., 5.4, 33.]
property_b = [ 1.2, 1.3, 2.3, 0.3]
...
и список с флагами одинаковой длины
good_objects = [True, False, False, True]
(который можно легко заменить эквивалентным списком индексов:
good_indices = [0, 3]
Что это самый простой способ для создания новых списков property_asel
, property_bsel
... которые содержат только значение , указанным либо в True
записях или индексы?
property_asel = [545., 33.]
property_bsel = [ 1.2, 0.3]
zip
в Python 2 создается новый список, а на Python 3 он просто возвращает (ленивый) генератор.from itertools import izip
и использовать это вместоzip
первого примера. Это создает итератор, такой же, как и в Python 3.Вижу 2 варианта.
Использование numpy:
property_a = numpy.array([545., 656., 5.4, 33.]) property_b = numpy.array([ 1.2, 1.3, 2.3, 0.3]) good_objects = [True, False, False, True] good_indices = [0, 3] property_asel = property_a[good_objects] property_bsel = property_b[good_indices]
Используя понимание списка и заархивируйте его:
property_a = [545., 656., 5.4, 33.] property_b = [ 1.2, 1.3, 2.3, 0.3] good_objects = [True, False, False, True] good_indices = [0, 3] property_asel = [x for x, y in zip(property_a, good_objects) if y] property_bsel = [property_b[i] for i in good_indices]
источник
[property_b[i] for i in good_indices]
хорош для использования безnumpy
Используйте встроенную функцию zip
property_asel = [a for (a, truth) in zip(property_a, good_objects) if truth]
РЕДАКТИРОВАТЬ
Просто посмотрите на новые возможности 2.7. Теперь в модуле itertools есть функция, аналогичная приведенному выше коду.
http://docs.python.org/library/itertools.html#itertools.compress
itertools.compress('ABCDEF', [1,0,1,0,1,1]) => A, C, E, F
источник
itertools.compress
здесь. Понимание списка гораздо более читабельно, без необходимости копаться в том, что делает чертов компресс.itertools.compress
вместо того, чтобы скопировать и вставить пример документации?Предполагая, что у вас есть только список элементов и список истинных / обязательных индексов, это должно быть самым быстрым:
property_asel = [ property_a[index] for index in good_indices ]
Это означает, что выбор свойства будет выполняться столько раундов, сколько есть истинных / требуемых индексов. Если у вас есть много списков свойств, которые следуют правилам одного списка тегов (true / false), вы можете создать список индексов, используя те же принципы понимания списка:
good_indices = [ index for index, item in enumerate(good_objects) if item ]
Это выполняет итерацию по каждому элементу в good_objects (запоминая его индекс с помощью enumerate) и возвращает только те индексы, в которых элемент является истинным.
Для тех, кто не понимает списка, вот английская версия прозы с кодом, выделенным жирным шрифтом:
перечисляет индекс для каждой группы индекса, элемент , который существует в качестве перечисления из хороших объектов , если (когда) элемент Правды
источник
Языки Matlab и Scilab предлагают более простой и элегантный синтаксис, чем Python, для вопроса, который вы задаете, поэтому я думаю, что лучшее, что вы можете сделать, - это имитировать Matlab / Scilab с помощью пакета Numpy в Python. Таким образом, решение вашей проблемы будет очень кратким и элегантным:
from numpy import * property_a = array([545., 656., 5.4, 33.]) property_b = array([ 1.2, 1.3, 2.3, 0.3]) good_objects = [True, False, False, True] good_indices = [0, 3] property_asel = property_a[good_objects] property_bsel = property_b[good_indices]
Numpy пытается имитировать Matlab / Scilab, но за это приходится платить: вам нужно объявить каждый список с ключевым словом «array», что приведет к перегрузке вашего скрипта (этой проблемы не существует с Matlab / Scilab). Обратите внимание, что это решение ограничено массивами чисел, как в вашем примере.
источник
filter
или внешнюю библиотеку Pythonpandas
. Если вы собираетесь поменять языки местами, вы также можете попробовать R, но вопрос не в этом .