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
.