seleccion multiple python list python-2.7

python - seleccion - notepad++ multiple cursors



Detener selección de lista? (2)

Imagina que tengo una lista de tuplas:

s = [(0,-1), (1,0), (2,-1), (3,0), (4,0), (5,-1), (6,0), (7,-1)]

Dado un parámetro X , quiero seleccionar todas las tuplas que tienen un primer elemento igual o mayor que X hasta, pero sin incluir, la primera tupla que tiene -1 como segundo elemento.

Por ejemplo, si X = 3 , quiero seleccionar la lista [(3,0), (4,0)]

Una idea que tuve fue: obtener la clave de corte con

E = min (x [0] for x in s if (x [0] >= X) and (x [1] == -1) )

Luego selecciona elementos con claves entre X y E :

R = [x for x in s if X <= x [0] < E]

Eso me da lo que quiero en R, pero parece realmente ineficiente, involucrando dos escaneos de tabla. Podría hacerlo en un bucle for, descartando tuplas con teclas demasiado pequeñas, y romper cuando golpee la primera tupla de bloqueo. Pero para carreras como un perro en comparación con la selección de la lista.

¿Hay una manera súper eficiente de python-esque (2.7) de hacer esto?


Aquí hay un poco hacky para implementar takewhile como parte de una expresión del generador:

def stop(): raise StopIteration result = ( stop() if item[1] == -1 else item for item in s if item[0] >= X )

O con diferentes frases:

def until(cond): if cond: raise StopIteration return True result = ( item for item in s if item[0] >= X and until(item[1] == -1) )


Simplemente puede filtrar las tuplas de la lista como una expresión de generador y luego puede dejar de tomar los valores de la expresión del generador cuando obtiene la primera tupla cuyo segundo elemento es -1 , como este

>>> s = [(0,-1), (1,0), (2,-1), (3,0), (4,0), (5,-1), (6,0), (7,-1)] >>> from itertools import takewhile >>> X = 3 >>> list(takewhile(lambda x: x[1] != -1, (item for item in s if item[0] >= X))) [(3, 0), (4, 0)]

Aquí, la expresión del generador, (item for item in s if item[0] >= X) dará valores uno a uno, a demanda, (no se generan todos a la vez, así que guardamos aquí la memoria) que son mayor que o igual a X

Entonces, tomamos valores de esa expresión del generador, solo hasta que encontremos una tupla cuyo segundo elemento no sea igual a -1 , con itertools.takewhile .