2010-11-24 16 views
56

¿Qué es más pitónico?Más Pythonic Forma de ejecutar un proceso X Tiempos

While:

count = 0 
while count < 50: 
    print "Some thing" 
    count = count + 1 

bucle For:

for i in range(50): 
    print "Some thing" 

Editar: no duplicar porque esto tiene respuestas para determinar qué es más clara, frente a cómo manejar un rango sin 'yo' - a pesar de que terminó siendo el más elegante

+7

Upvoting con el fin para compensar los votos a la baja: si Lionel hace esta pregunta, otros pueden Tengo la misma pregunta, y las respuestas a continuación serán útiles. – EOL

+2

Término "Pythonic" está siendo usado en exceso. Es un sinónimo de "legible" y "fácilmente comprensible". En Python, al menos. – darioo

+0

Posible duplicado de [¿Es posible implementar un Python para el bucle de rango sin una variable de iterador?] (Http://stackoverflow.com/questions/818828/is-it-possible-to-implement-a-python-for- range-loop-without-an-iterator-variable) –

Respuesta

72

Personalmente:

for _ in range(50): 
    print "Some thing" 

si no es necesario i. Si usa Python < 3 y quiere repetir el ciclo muchas veces, use xrange ya que no es necesario generar toda la lista de antemano.

+10

Sin embargo, tenga cuidado de que _ se haya asignado a la función de traducción gettext. –

+6

+1 para la variable '_'. Esto es lo que hubiera sugerido. – EOL

+0

Gracias por esta respuesta; esta fue la razón principal por la que no estaba usando el bucle for porque tenía una variable no utilizada en "i". – Lionel

1

Si usted está después de la s Los efectos que ocurren dentro del ciclo, yo personalmente elegiré el enfoque range().

Si le importa el resultado de cualquiera de las funciones que llama dentro del ciclo, yo elegiría una lista de comprensión o map. Algo como esto:

def f(n): 
    return n * n 

results = [f(i) for i in range(50)] 
# or using map: 
results = map(f, range(50)) 
+0

results = (f para i en el rango (50)) –

+1

results = itertools.imap (f, rango (50)) –

+0

@ralu, solo si no necesita acceso repetido o aleatorio a los resultados sin embargo. – aaronasterling

-6

No hay una manera realmente pitónica de repetir algo. Sin embargo, es una mejor manera:

mapa (índice lambda: hacer_algo(), xrange (10))

si usted necesita para pasar el índice a continuación:

mapa (índice lambda: hacer_algo (index), xrange (10))

Considere que devuelve los resultados como una colección, por lo que si necesita recopilar los resultados, puede ayudar.

+0

No solo esto no es realmente mejor (sobrecarga de llamada de función, expresiones lambda menos conocidas, recopilación de resultados no utilizados en una lista), 10 no es iterable. –

+0

Sí, xrange (10) no 10. Dije que es mejor porque no necesita escribir una función o hacer un ciclo. Sin embargo, como dije, no hay una forma realmente pitonica. Cambié el código, gracias. –

1

El bucle for es definitivamente más pitónico, ya que utiliza la funcionalidad integrada de nivel superior de Python para transmitir lo que está haciendo de forma más clara y concisa. La sobrecarga del rango frente a xrange y la asignación de una variable i no utilizada provienen de la ausencia de una declaración como la declaración repeat de Verilog. La razón principal para apegarse a la solución de rango for es que otras formas son más complejas. Por ejemplo:

from itertools import repeat 

for unused in repeat(None, 10): 
    del unused # redundant and inefficient, the name is clear enough 
    print "This is run 10 times" 

El uso de la repetición en lugar de gama aquí no está tan claro, porque no es tan conocido una función, y más complejo porque hay que importarlo. Las guías de estilo principales si necesita una referencia son PEP 20 - The Zen of Python y PEP 8 - Style Guide for Python Code.

Observamos también que la versión de gama es un ejemplo explícito utilizado tanto en el language reference y tutorial, aunque en este caso se utiliza el valor. Significa que la forma está destinada a ser más familiar que la expansión while de un C-style for loop.

+0

¿No sería mejor usar lo repetido directamente, es decir: 'para s en repeat ('Esto se ejecuta 10 veces', 10): imprimir s' ?? – F1Rumors

+0

¡Ciertamente! Pero la impresión en el código de muestra era solo un ejemplo de una sección repetida de código, para la cual no puede haber un objeto central. –

-4

¿Qué tal?

while BoolIter(N, default=True, falseIndex=N-1): 
    print 'some thing' 

o de una manera más fea:

for _ in BoolIter(N): 
    print 'doing somthing' 

o si quieres coger el último tiempo a través de:

for lastIteration in BoolIter(N, default=False, trueIndex=N-1): 
    if not lastIteration: 
     print 'still going' 
    else: 
     print 'last time' 

donde:

class BoolIter(object): 

    def __init__(self, n, default=False, falseIndex=None, trueIndex=None, falseIndexes=[], trueIndexes=[], emitObject=False): 
     self.n = n 
     self.i = None 
     self._default = default 
     self._falseIndexes=set(falseIndexes) 
     self._trueIndexes=set(trueIndexes) 
     if falseIndex is not None: 
      self._falseIndexes.add(falseIndex) 
     if trueIndex is not None: 
      self._trueIndexes.add(trueIndex) 
     self._emitObject = emitObject 


    def __iter__(self): 
     return self 

    def next(self): 
     if self.i is None: 
      self.i = 0 
     else: 
      self.i += 1 
     if self.i == self.n: 
      raise StopIteration 
     if self._emitObject: 
      return self 
     else: 
      return self.__nonzero__() 

    def __nonzero__(self): 
     i = self.i 
     if i in self._trueIndexes: 
      return True 
     if i in self._falseIndexes: 
      return False 
     return self._default 

    def __bool__(self): 
     return self.__nonzero__() 
Cuestiones relacionadas