2010-03-23 12 views
30

Supongamos que tengo una lista que deseo no devolver, pero para obtener valores de. ¿Cuál es la forma más pitónica de hacer eso?Cómo obtener Pythonically todos los valores de una lista?

Esto es lo que quiero decir. Gracias a algunos cálculos no perezosos, he calculado la lista ['a', 'b', 'c', 'd'], pero mi código a través del proyecto usa cálculos perezosos, por lo que me gustaría obtener valores de mi función en lugar de devolver toda la lista.

actualmente lo escribí la siguiente manera:

my_list = ['a', 'b', 'c', 'd'] 
for item in my_list: 
    yield item 

Pero esto no se siente Pythonic a mí.

+3

¿Por qué necesitas hacer eso, puedes usar "para x en contenedor" donde contenedor es una lista o contenedor es un iterador ... la sintaxis no cambia independientemente del tipo, entonces ¿por qué importa si es una lista? o un iterador? Todavía tendrá que esperar en la lista para ceder, así que simplemente pase la lista. –

+0

Comentario adicional: con "Lista", mucha gente lo considerará como un nombre de clase debido a la mayúscula inicial (ver PEP 8). Puede usar "list_", o "my_list", etc. – EOL

+0

EOL, agradezco su comentario. Gracias. – bodacydo

Respuesta

28

Uso iter para crear un iterador de la lista, por ejemplo,

return iter(List) 

aunque si ya tiene una lista, que sólo puede devolver ese, que será más eficiente.

+0

Buena pregunta. Y no tengo respuesta Devolveré toda la lista. Solo pensé que devolver un generador era una buena idea porque todo en el proyecto usaba generadores (excepto este lugar, obtengo esta lista de una biblioteca que no es floja). – bodacydo

+3

Esto es excesivo ya que la llamada a 'iter' es completamente redundante. – msw

+2

'iter' es una exageración pero no es completamente redundante, se puede usar para recordar dónde se encuentra mientras se itera en una lista y se puede pasar, junto con la lista también deberá pasar un índice –

1

Se puede construir un generador diciendo

(x for x in List) 
+0

Entonces, ¿puedo hacer 'return (x para x en la lista)'? – bodacydo

+1

Sí. Pero no creo que te ahorrará mucho esfuerzo, ya que ya has calculado la lista completa, ¿por qué no la devuelves? –

+6

El iter incorporado() hace esto por usted: no hay necesidad de una expresión de generador, que también tiene la desventaja de ser más lenta. – EOL

34

Dado que esta pregunta no especifica; Proporcionaré una respuesta que se aplica en Python >= 3.3

Si solo necesita devolver esa lista, haga lo que Anurag suggests, pero si por alguna razón la función en cuestión realmente necesita ser un generador, puede delegar a otro generador; supongamos que desea sufijo la lista de resultados, pero solo si la lista se agota por primera vez.

def foo(): 
    list_ = ['a', 'b', 'c', 'd'] 
    yield from list_ 

    if something: 
     yield this 
     yield that 
     yield something_else 

En las versiones de python anteriores a la versión 3.3, sin embargo, no puede usar esta sintaxis; tendrá que usar el código como en la pregunta, con un bucle for y una declaración de rendimiento único en el cuerpo.

Alternativamente; se puede envolver los generadores en función regular y devolver el resultado chain ed: Esto también tiene la ventaja de trabajar en Python 2 y 3 vías

from itertools import chain 

def foo(): 
    list_ = ['a', 'b', 'c', 'd'] 

    def _foo_suffix(): 
     if something: 
      yield this 
      yield that 
      yield something_else 

    return chain(list_, _foo_suffix()) 
+14

La función 'yield from list_' es una sintaxis agradable, y es lo que vine a buscar aquí. Lástima que no puedo usarlo en 2.7. –

0

Mejor Pythonically para realizar esta tarea es

In [1]: my_list = ['a', 'b', 'c', 'd'] 

In [2]: (x for x in my_list) 
Out[2]: <generator object <genexpr> at 0x7fd9e4fdc230> 
Cuestiones relacionadas