2013-09-04 3 views
0

У меня есть два списка одинаковой длины:Удалить элемент из списка, если он удовлетворяет условие, определенное из отдельного списка - Python

Offset = [-0.0002, -0.0004, -0.0004, -0.006, -0.0006, -0.0006, -0.0066, -0.0007, -0.0007, -0.0008] 

Ratio = [0.0641, 0.152, 0.254, 0.246, 0.3197, 0.3249, 2.8795, 0.4286, 0.5191, 0.5712] 

Что я хотел бы сделать, это создать список, элементы которого происходит от смещения при условии, что соответствующий элемент в коэффициенте составляет менее 2.5. Итак, для двух списков выше, 6-й элемент в Ratio больше 2.5, и я хочу, чтобы затем удалить 6-й элемент в Offset и вернуть все остальные элементы.

Я пытался сделать список понимание, моя попытка:

Data = [x for n in Ratio[n] for x in Offset if Ratio[n] < 2.5] 

Однако это производит объект «numpy.float64» ошибка не итератора», который от чтения this question я могу понять, почему я получить ошибку, но я не уверен, как сделать работу по составлению списка.

Этот цикл, кажется, находится на правильных дорожках, но a) я бы предпочел понимание списка и b) Я не думаю, что вы можете удалять элементы в списке, итерации по нему.

for n in range(len(Ratio)): 

    if Ratio[n] < 2.5: 
    #Keep the element Offset[n] 
    else: 
    #Delete the element Offset[n] 
+2

Просто хотел добавить что-то, что может вас заинтересовать. В Python вы можете удалять элементы из списка, итерации по нему. Вам просто нужно повторить BACKWARDS, чтобы смена списка не влияла на ваш будущий путь. Это позволит избежать любых ошибок вне границ с индексами списка. – Shashank

+0

Я этого не знал, спасибо. – Holtz

ответ

4

Это даст список, который вы ищете. Ключ должен использовать zip (или izip, если вы предпочитаете), когда у вас есть списки с соответствующими элементами.

[offset for offset, ratio in zip(Offset, Ratio) if ratio < 2.5] 
+1

Должно быть '<'. – flornquake

+0

Спасибо. Я также обнаружил, что когда я провел тест. –

4

Это звучит из сообщения об ошибке

'numpy.float64' object is not iterable' 

что Ratio является NumPy массив. Если оба Offset и Ratio являются Numpy массивы, то вы можете сформировать массив вы хотите с

Offset[Ratio < 2.5] 

Например:

In [1]: import numpy as np 

In [2]: Ratio = np.array([0.0641, 0.152, 0.254, 0.246, 0.3197, 0.3249, 2.8795, 0.4286, 0.5191, 0.5712]) 

In [3]: Offset = np.array([-0.0002, -0.0004, -0.0004, -0.006, -0.0006, -0.0006, -0.0066, -0.0007, -0.0007, -0.0008]) 

In [7]: Offset[Ratio < 2.5] 
Out[7]: 
array([-0.0002, -0.0004, -0.0004, -0.006 , -0.0006, -0.0006, -0.0007, 
     -0.0007, -0.0008]) 
+0

Я готов поспорить, это самый быстрый способ. – Marcin

0

Ваш первоначальный список понимание может быть сделано для работы с использованием enumerate.

Data = [x for (i, x) in enumerate(Offset) if Ratio[i] < 2.5] 


Который оказывается быстрее, чем zip, но медленнее, чем izip в Python 2.7:

from time import time 
from itertools import izip 

Offset = [-0.0002, -0.0004, -0.0004, -0.006, -0.0006, -0.0006, -0.0066, -0.0007, -0.0007, -0.0008] 
Ratio = [0.0641, 0.152, 0.254, 0.246, 0.3197, 0.3249, 2.8795, 0.4286, 0.5191, 0.5712] 

def _enumerate(): 
    return [x for (i, x) in enumerate(Offset) if Ratio[i] < 2.5] 

def _zip(): 
    return [offset for offset, ratio in zip(Offset, Ratio) if ratio < 2.5] 

def _izip(): 
    return [offset for offset, ratio in izip(Offset, Ratio) if ratio < 2.5] 

assert _enumerate() == _zip() == _izip() 

for f in (_enumerate, _zip, _izip): 
    start = time() 
    for i in range(10000): 
     f() 
    print '%s: %s' % (time() - start, f.func_name) 

Выход:

0.0142180919647: _enumerate 
0.0157129764557: _zip 
0.0130951404572: _izip 
+0

В Python 3 'zip' возвращает итерабельность и быстрее, чем использование' enumerate'. В Python 2, где 'zip' возвращает список, используйте' itertools.izip' для максимальной эффективности. – flornquake

+0

Полезно знать. Я тестировал Python 2.7.3. Благодаря! – derek

Смежные вопросы