2012-02-07 2 views
3

У меня есть 3 списков x, y, z и я сюжет их:Python Подсписок для условия

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

Что это самый простой способ только построить точки, где x > 0.5?

(моя проблема заключается в том, как определить подсписку при условии без создания цикла для этого списка).

ответ

1

Это невозможно проверить состояние на каждом элементе списка без iterati по крайней мере один раз. Вы можете использовать NumPy здесь для легкого доступа к элементам после того, как условие passsed и сделать:

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

Я не уверен, почему вы избегаете перебирать список, и я предполагаю, что вы хотите, чтобы связанные пункты в других списках также удалялись.

>>> 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)] 

Разделение списка в его составные списки потребует циклического перебора по списку.

+3

, разделяющее список обратно в отдельные списки можно сделать с другим вызовом ZIP: 'F = [item для элемента в zip (x, y, z), если item [0]> 0.5]; zip (* f) ' – lvc

+0

@lvc Мне это нравится! Вы должны добавить это как ответ, и это должно быть принято! –

3

Простой список понимания не будет достаточно, чтобы удалить (х, у, г) кортежи, если х < = 0,5, вы должны будете сделать немного больше, я использую 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') 

EDIT: После и модернизации @shenshei совет, который мы можем достичь его с помощью одной строки:

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

вы также можете сделать 'x, y, z = zip (* result)' – shenshei

+0

Не должно быть: 'x = [itemgetter (0) (point) для результата в результате]'? –

+0

@shenshei: Я беру ваше замечание, и я использовал его в один лайнер :) –

1

Я не хочу, чтобы украсть гром СНА, но вот вариант на их ответ:

>>> 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') 
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() нет более длинный precomputes полный список при вызове - это может повредить использование памяти и скорость, особенно если количество точек велико.

2

Возможно, использование numpy обеспечит самый чистый подход. Однако вам понадобятся списки/массивы x, y и z как 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).

Используйте эти показатели, чтобы выбрать только те конкретные пункты в x, y и z, которые удовлетворяют желаемое состояние:

ax.plot3D(x[idx], y[idx], z[idx], linestyle = 'None', marker = 'o') 
Смежные вопросы