없이 다음을 수행 할 수 i
있습니까?
for i in range(some_number):
# do something
N 번 무언가를하고 반복자가 필요없는 경우.
없이 다음을 수행 할 수 i
있습니까?
for i in range(some_number):
# do something
N 번 무언가를하고 반복자가 필요없는 경우.
답변:
내 머리 꼭대기에서
나는 당신이 할 수있는 최선의 방법은 다음과 같다고 생각합니다.
def loop(f,n):
for i in xrange(n): f()
loop(lambda: <insert expression here>, 5)
그러나 나는 당신이 여분의 i
변수로 살 수 있다고 생각합니다 .
다음은 _
실제로 다른 변수 인 변수 를 사용하는 옵션 입니다.
for _ in range(n):
do_something()
참고 _
대화 형 파이썬 세션에서 반환 된 마지막 결과를 할당 :
>>> 1+2
3
>>> _
3
이런 이유로 나는 이런 식으로 사용하지 않을 것입니다. Ryan이 언급 한 바와 같이 어떤 관용구도 알지 못합니다. 통역사가 엉망이 될 수 있습니다.
>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9
Python grammar 에 따르면 허용되는 변수 이름입니다.
identifier ::= (letter|"_") (letter | digit | "_")*
_
하면 무시해야한다는 것이 분명해집니다. 이 작업에 아무런 의미가 없다고 말하는 것은 코드를 주석 처리 할 때 아무런 의미가 없다고 말하는 것과 같습니다. 왜냐하면 어쨌든 정확히 동일하기 때문입니다.
당신은 찾고 있습니다
for _ in itertools.repeat(None, times): ...
이것은 times
파이썬에서 시간 을 반복하는 가장 빠른 방법 입니다.
_ 사용을 제안하는 모든 사람들이 말하는 것은 아닙니다. _는 gettext 함수 중 하나에 대한 바로 가기로 자주 사용 되므로 소프트웨어를 여러 언어로 사용할 수있게하려면 사용하지 않는 것이 좋습니다. 다른 목적으로.
import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')
_
끔찍한 생각처럼 보이고, 나는 그것을 상충하지 않을 것입니다.
다음은 데이터 모델 ( Py3 link ) 을 활용하는 임의의 아이디어입니다 .
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
표준 라이브러리에 이와 같은 것이 있는지 궁금합니다.
__nonzero__
부작용과 같은 방법을 사용하는 것이 끔찍한 생각이라고 생각합니다.
__call__
대신에 사용하겠습니다 . while x():
작성하기가 그리 어렵지 않습니다.
Counter
. 확실히, 그것은 예약되거나 내장 된 범위에 있지 않지만 collections.Counter
사물 이며 같은 이름의 클래스를 만들면 관리자가 혼란에 빠질 수 있습니다 (이것은 이미 위험하지 않습니다).
반복자를 사용하는 데 어떤 문제가 있는지에 대한 답이 될 수 있습니까? 사용되었을지도 모른다
i = 100
while i:
print i
i-=1
또는
def loop(N, doSomething):
if not N:
return
print doSomething(N)
loop(N-1, doSomething)
loop(100, lambda a:a)
그러나 솔직히 나는 그러한 접근법을 사용하는 데 아무런 의미가 없습니다.
sys.getrecursionlimit()
(기본값은 하위 4의 어딘가에 있습니다) CPython의 숫자 범위); 를 사용 sys.setrecursionlimit
하면 한계가 높아지지만 결국 C 스택 한계에 도달하면 인터프리터는 스택 오버플로로 죽을 것입니다 (좋은 RuntimeError
/를 올리는 것뿐만 아니라 RecursionError
).
t=0
for _ in range(10):
print t
t = t+1
산출:
0
1
2
3
4
5
6
7
8
9
불필요한 카운터 대신 이제 불필요한 목록이 있습니다. 가장 좋은 해결책은 "_"로 시작하는 변수를 사용하는 것입니다.이 변수는 구문 검사기에게 변수를 사용하고 있지 않다는 것을 알려줍니다.
x = range(5)
while x:
x.pop()
print "Work!"
나는 일반적으로 위에 주어진 해결책에 동의합니다. 즉 :
for
-loop 에서 밑줄 사용 (2 줄 이상)while
카운터 정의 (3 줄 이상)__nonzero__
구현 으로 커스텀 클래스 선언 하기 (많은 줄)하나 같이 객체를 정의하는 경우 # 3 난에 대한 프로토콜을 구현하는 것이 좋습니다 와 키워드 또는 적용 contextlib을 .
또한 나는 또 다른 해결책을 제안합니다. 3 라이너이며 최고의 우아함은 아니지만 itertools 패키지를 사용하므로 관심이있을 수 있습니다.
from itertools import (chain, repeat)
times = chain(repeat(True, 2), repeat(False))
while next(times):
print 'do stuff!'
이 예에서 2 는 루프를 반복하는 횟수입니다. chain 은 두 개의 반복 반복자를 감싸고 있으며 첫 번째는 제한적이지만 두 번째는 무한합니다. 이들은 진정한 반복자 객체이므로 무한 메모리가 필요하지 않습니다. 분명히 이것은 솔루션 # 1 보다 훨씬 느립니다 . 함수의 일부로 작성되지 않는 한 시간 동안 변수 정리가 필요할 수 있습니다 .
chain
불필요 times = repeat(True, 2); while next(times, False):
하고 같은 일을합니다.
우리는 다음과 같이 재미있었습니다.
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()
결과 :
0
1
2
3
4
5
6
---------
7
경우 do_something
간단한 기능 또는 하나의 간단한에 싸여 할 수 map()
캔 do_something
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)
에 인수를 전달 do_something
하려면 itertools repeatfunc
레시피 가 잘 읽힐 수도 있습니다 .
동일한 인수를 전달하려면 다음을 수행하십시오.
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)
다른 인수를 전달하려면 다음을 수행하십시오.
argses = [(1, 2), (3, 4), ...]
deque(starmap(do_something, argses), 0)
당신이 경우 정말 이름으로 뭔가를 넣어 (반복의 영업과 같이 변수 또는 원치 않는 목록 또는 시간의 진정한 원하는 금액을 반환 원치 않는 발전기 중 하나) 당신이 정말 원한다면 당신이 그것을 할 수 않도록하려면 :
for type('', (), {}).x in range(somenumber):
dosomething()
사용되는 트릭은 type('', (), {})
빈 이름의 클래스 를 생성하는 익명 클래스를 작성하는 것이지만 NB는 로컬 또는 글로벌 네임 스페이스에 삽입되지 않습니다 (빈 이름이 제공되지 않은 경우에도). 그런 다음 해당 클래스의 멤버를 멤버로 사용하는 클래스에 도달 할 수 없으므로이 클래스의 멤버를 반복 변수로 사용하십시오.
#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))
이건 어떤가요:
while range(some_number):
#do something
range(some_number)
이 항상 참이므로 무한 루프 입니다!
some_number
이보다 작거나 같으면 0
무한하지 않고 결코 실행되지 않습니다. 그것은 신선한 작성하기 :-) 그리고, (특히 Py2에) 무한 루프 오히려 비효율적이다 list
(Py2) 또는 range
각 시험 객체 (Py3)을 (그것이 부하가,보기의 통역의 관점에서 일정한 아니다 range
및 some_number
모든 루프를 호출 range
하고 결과를 테스트하십시오).