Pergunta

É possível fazer seguinte sem a i?

for i in range(some_number):
    # do something

Se você quiser apenas fazer montante N algo de vezes e não precisa do iterador.

Foi útil?

Solução

Em cima da minha cabeça, não.

Eu acho que o melhor que você pode fazer é algo como isto:

def loop(f,n):
    for i in xrange(n): f()

loop(lambda: <insert expression here>, 5)

Mas eu acho que você pode viver apenas com a variável i extra.

Aqui está a opção de usar a variável _, que, na realidade, é apenas uma outra variável.

for _ in range(n):
    do_something()

Note que _ é atribuído o último resultado que retornou em uma sessão de python interativo:

>>> 1+2
3
>>> _
3

Por esta razão, eu não iria usá-lo dessa maneira. Não tenho conhecimento de qualquer idioma como mencionado por Ryan. Ele pode atrapalhar o seu intérprete.

>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9

E de acordo com Python gramática , é um nome de variável aceitável :

identifier ::= (letter|"_") (letter | digit | "_")*

Outras dicas

Você pode estar procurando

for _ in itertools.repeat(None, times): ...

Esta é a maneira mais rápida de vezes times ITERATE em Python.

O idioma geral para a atribuição de um valor que não é usado é nomeá-lo _.

for _ in range(times):
    do_stuff()

O que todos sugerindo que você use _ não está dizendo é que _ é frequentemente usado como um atalho para um dos gettext funções, por isso, se você quer que seu software para estar disponível em mais de um idioma, então você é melhor fora evitando utilizá-lo para outros fins.

import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')

Aqui está uma ideia aleatória que utiliza (abusos?) O href="https://docs.python.org/2/reference/datamodel.html#object.__nonzero__" rel="nofollow noreferrer"> modelo de dados ( PY3 ligação ).

class Counter(object):
    def __init__(self, val):
        self.val = val

    def __nonzero__(self):
        self.val -= 1
        return self.val >= 0
    __bool__ = __nonzero__  # Alias to Py3 name to make code work unchanged on Py2 and Py3

x = Counter(5)
while x:
    # Do something
    pass

Gostaria de saber se existe algo como isto nas bibliotecas padrão?

Você pode usar _11 (ou qualquer número ou outro identificador inválido) para evitar name-colisão com gettext. Toda vez que você usar sublinhado + inválido identificador você recebe um nome fictício que pode ser usado em loop for.

Pode ser a resposta vai depender de qual é o problema que você tem com o uso de iterador? pode ser usado

i = 100
while i:
    print i
    i-=1

ou

def loop(N, doSomething):
    if not N:
        return
    print doSomething(N)
    loop(N-1, doSomething)

loop(100, lambda a:a)

mas francamente eu vejo nenhum ponto em usar tais abordagens

t=0    
for _ in range(10):
    print t
    t = t+1

SAÍDA:

0
1 
2 
3 
4 
5 
6 
7
8
9

Eu geralmente concordam com as soluções dadas acima. Nomeadamente com:

  1. Usando sublinhado em for-circuito (2 e mais linhas)
  2. A definição de um contador while normal (3 e mais linhas)
  3. Declarando uma classe personalizada com a implementação __nonzero__ (muitas mais linhas)

Se um é definir um objeto como em # 3 Eu recomendaria implementação protocolo para com palavra-chave ou aplicar contextlib .

Além disso proponho outra solução. É um revestimento 3 e não é de suprema elegância, mas ele usa itertools pacote e, assim, pode ser do seu interesse.

from itertools import (chain, repeat)

times = chain(repeat(True, 2), repeat(False))
while next(times):
    print 'do stuff!'

Nestes exemplo 2 é o número de vezes para iterar a ansa. cadeia está envolvendo dois repetição fortes iterators, sendo o primeiro limitado, mas o segundo é infinita. Lembre-se que estes são verdadeiros objetos iteradores, portanto, eles não precisam de memória infinita. Obviamente, isso é muito mais lento, em seguida, solução de # 1 . A não ser escrito como uma parte de uma função que pode exigir uma limpeza para vezes variável.

Nós tivemos um pouco de diversão com o seguinte, interessante para compartilhar isso:

class RepeatFunction:
    def __init__(self,n=1): self.n = n
    def __call__(self,Func):
        for i in xrange(self.n):
            Func()
        return Func


#----usage
k = 0

@RepeatFunction(7)                       #decorator for repeating function
def Job():
    global k
    print k
    k += 1

print '---------'
Job()

Resultados:

0
1
2
3
4
5
6
---------
7

Se do_something é uma função simples ou pode ser envolvido em um, um map() simples pode do_something vezes range(some_number):

# Py2 version - map is eager, so it can be used alone
map(do_something, xrange(some_number))

# Py3 version - map is lazy, so it must be consumed to do the work at all;
# wrapping in list() would be equivalent to Py2, but if you don't use the return
# value, it's wastefully creating a temporary, possibly huge, list of junk.
# collections.deque with maxlen 0 can efficiently run a generator to exhaustion without
# storing any of the results; the itertools consume recipe uses it for that purpose.
from collections import deque

deque(map(do_something, range(some_number)), 0)

Se você quiser passar argumentos para do_something, você também pode encontrar o itertools repeatfunc receita lê bem:

Para passar os mesmos argumentos:

from collections import deque
from itertools import repeat, starmap

args = (..., my args here, ...)

# Same as Py3 map above, you must consume starmap (it's a lazy generator, even on Py2)
deque(starmap(do_something, repeat(args, some_number)), 0)

Para passar argumentos diferentes:

argses = [(1, 2), (3, 4), ...]

deque(starmap(do_something, argses), 0)

Em vez de um contador desnecessários, agora você tem uma lista desnecessários. A melhor solução é usar uma variável que começa com "_", que conta damas de sintaxe que você está ciente de que você não está usando a variável.

x = range(5)
while x:
  x.pop()
  print "Work!"

Se você realmente quer evitar colocar algo com um nome (ou uma variável de iteração como no OP, ou lista indesejada ou gerador indesejado retornando true o valor queria de tempo), você poderia fazê-lo se você realmente queria:

for type('', (), {}).x in range(somenumber):
    dosomething()

O truque que é usado é criar um type('', (), {}) classe anônima que resulta em uma classe com o nome vazio, mas NB que não está inserido no espaço de nomes local ou global (mesmo que um nome não vazio foi fornecido). Então você usa um membro dessa classe como variável de iteração que é inacessível desde que a classe é um membro é inacessível.

#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))

http://docs.python.org/2/library/itertools. html

E:

while range(some_number):
    #do something
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top