Python:根据索引集从列表中select子集
我有几个列表具有所有相同数量的条目(每个指定对象属性):
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] 
	
你可以使用列表理解 :
 property_asel = [val for is_good, val in zip(good_objects, property_a) if is_good] 
要么
 property_asel = [property_a[i] for i in good_indices] 
 后者更快,因为good_indices的数量less于good_indices的长度,假设good_indices是预先计算的而不是即时生成的。 
  编辑 :第一个选项等同于自Python 2.7 / 3.1以来可用的itertools.compress 。 见@加里·克尔的答案。 
 property_asel = list(itertools.compress(good_objects, property_a)) 
我看到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]
使用内置的函数zip
 property_asel = [a for (a, truth) in zip(property_a, good_objects) if truth] 
编辑
只要看看2.7的新function。 现在在itertools模块中有一个类似于上面代码的函数。
http://docs.python.org/library/itertools.html#itertools.compress
 itertools.compress('ABCDEF', [1,0,1,0,1,1]) => A, C, E, F 
假设你只有项目列表和真实/必需的索引列表,这应该是最快的:
 property_asel = [ property_a[index] for index in good_indices ] 
这意味着房地产select只会有真实/必需的指数。 如果您有很多属性列表遵循单个标签(true / false)列表的规则,则可以使用相同的列表理解原则创build索引列表:
 good_indices = [ index for index, item in enumerate(good_objects) if item ] 
这遍历了good_objects中的每个项目(同时用枚举记住它的索引),并只返回项目为真的索引。
对于没有得到清单理解的人来说,这里是一个英文散文版本,其代码以粗体突出显示:
列出每个索引的索引,这个索引是存在于一个好的对象 枚举中的, 如果 (where)该项是真的
Matlab和Scilab语言提供了一个比Python更简单,更优雅的语法,因此我认为您可以做的最好的方法是使用Python中的Numpy包来模拟Matlab / Scilab。 通过这样做你的问题的解决scheme是非常简洁和优雅:
 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中不存在)。 请注意,这个解决scheme仅限于数组的数组,这是你的例子。