条件的Python子列表

时间:2012-02-07 10:54:50

标签: python list

我有3个列表xyz,我将它们绘制成:

ax.plot3D(x, y, z, linestyle = 'None', marker = 'o').

仅绘制x > 0.5

点的最简单方法是什么?

(我的问题是如何在条件下定义子列表而不在该列表上进行for循环)。

6 个答案:

答案 0 :(得分:4)

我不确定你为什么要避免在列表上循环,我假设你希望其他列表中的相关点也被删除。

>>> x = [0.0, 0.4, 0.6, 1.0]
>>> y = [0.0, 2.2, 1.5, 1.6]
>>> z = [0.0, 9.1, 1.0, 0.9]
>>> zip(x,y,z)
[(0.0, 0.0, 0.0), (0.4, 2.2, 9.1), (0.6, 1.5, 1.0), (1.0, 1.6, 0.9)]
>>> [item for item in zip(x,y,z) if item[0] > 0.5]
[(0.6, 1.5, 1.0), (1.0, 1.6, 0.9)]

将列表分成它的组成列表将需要以某种方式循环遍历列表。

答案 1 :(得分:3)

如果x <= 0.5,那么简单的列表理解就不足以删除(x,y,z)元组,你需要多做一点,我使用operator.itemgetter作为第二个部分:

from operator import itemgetter

result = [(a, b, c) for a,b,c in zip(x,y,z) if a > 0.5] # first, remove the triplet
x = itemgetter(0)(result)  # then grab from the new list the x,y,z parts
y = itemgetter(1)(result)
z = itemgetter(2)(result)

ax.plot3D(x, y, z, linestyle="None, marker='o')

修改 跟随并升级@shenshei建议我们可以用一行来实现它:

ax.plot3D(
  *zip(*[(a, b, c) for a,b,c in zip(x,y,z) if a > 0.5]), 
  linestyle="None, 
  marker='o'
)

答案 2 :(得分:2)

无法在列表的每个元素上验证条件,而不至少迭代一次。你可以使用numpy在条件传递后轻松访问元素并执行:

 import numpy
 x = [0.0, 0.4, 0.6, 1.0]
 y = [0.0, 2.2, 1.5, 1.6]
 z = [0.0, 9.1, 1.0, 0.9]
 res = numpy.array([[x[i], y[i], z[i]] for i in xrange(len(x)) if x[i] > 0.5])
 ax.plot3D(res[:,0], res[:,1], res[:,2], linestyle="None, marker='o'")

答案 3 :(得分:2)

可能使用numpy会提供最干净的方法。但是,您需要将列表/数组xyz作为numpy数组。因此,首先将这些列表转换为numpy数组:

import numpy as np
x = np.asarray(x)
y = np.asarray(y)
z = np.asarray(z)

现在计算满足条件的元素索引数组:

idx = np.where(x > 0.5)

注意:或者,你可以计算一个布尔掩码:idx=x>0.5(这不会改变下一个idx语句中ax.plot3D的使用。)

使用这些索引仅选择满足所需条件的xyz中的特定点:

ax.plot3D(x[idx], y[idx], z[idx], linestyle = 'None', marker = 'o')

答案 4 :(得分:1)

我不想窃取lvc的雷声,但这是他们答案的变体:

>>> x = [0.1, 0.6, 0.2, 0.8, 0.9]
>>> y = [0.3, 0.1, 0.9, 0.5, 0.8]
>>> z = [0.9, 0.2, 0.7, 0.4, 0.3]
>>> 
>>> a, b, c = zip(*filter(lambda t: t[0] > 0.5, zip(x, y, z)))
>>> print a, "\n", b, "\n", c
(0.6, 0.8, 0.9) 
(0.1, 0.5, 0.8) 
(0.2, 0.4, 0.3)
>>> ax.plot3D(a, b, c, linestyle = 'None', marker = 'o')

答案 5 :(得分:1)

根据@StephenPaulger的建议,将我的评论作为答案重新发布。您可以使用生成器表达式和对内置zip()

的几个调用来执行此操作
x = [0.0, 0.4, 0.6, 1.0]
y = [0.0, 2.2, 1.5, 1.6]
z = [0.0, 9.1, 1.0, 0.9]

points = (point for point in zip(x, y, z) if point[0] > 0.5)
x, y, z = zip(*points)

如果你愿意,你也可以使用points的列表理解,但是 - 假设Python 3,zip()在调用时不再预先计算完整列表 - 这可能会损害你的内存使用和速度,特别是如果点数很大的话。