프로세스를 X 번 실행하는 더 파이썬적인 방법


90

어느 것이 더 비단뱀입니까?

While 루프 :

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

For 루프 :

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

편집 : 중복되지 않는 이유는 'i'없이 범위를 실행하는 방법과 비교해 더 명확한 결정에 대한 답변이 있기 때문입니다.


8
반대표를 보상하기위한 찬성 : Lionel이이 질문을하면 다른 사람들이 동일한 질문을 할 수 있으며 아래 답변이 유용 할 것입니다.
— Eric O Lebigot

2
"Pythonic"이라는 용어가 남용되고 있습니다. "읽기"와 "쉽게 이해하기"의 동의어입니다. 파이썬에서는 적어도.
— darioo 2010

답변:


111

몸소:

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

필요하지 않은 경우 i. Python <3을 사용하고 루프를 여러 번 반복하려면 xrange미리 전체 목록을 생성 할 필요가 없으므로 사용 하십시오.


15
하지만 _이 gettext 번역 기능에 매핑되는지 확인하십시오.
— Gintautas Miliauskas 2010

이 답변에 감사드립니다. 이것이 내가 "i"에 사용되지 않은 변수가 있었기 때문에 for-loop를 사용하지 않은 주된 이유였습니다.
— Lionel

6
_는 다른 변수와 같습니다. REPL에서만 특별한 의미가 있습니다. OP는 i.
— vezult

2
@vezult 변수가 문에서 사용되지 않는다는 것을 분명히하기 때문에 나는 이것을 좋아합니다. 아마도 이것을 어둡게하는 이유가 i있습니까?
— ryanjdillon 2013

6
나는 조랑말을 추가하는 것을 굳게 믿습니다. 특히 적절하게 들릴 때 ... for pony in range (50) : print ( "neigh") #python 3
— Paul

3

for 루프는 더 명확하고 간결하게 수행하는 작업을 전달하기 위해 Python의 더 높은 수준의 내장 기능을 사용하기 때문에 확실히 더 파이썬 적입니다. range 대 xrange의 오버 헤드와 사용하지 않는 i변수를 할당하는 것은 Verilog의 repeat명령문 과 같은 명령문이 없기 때문입니다 . for range 솔루션을 고수하는 주된 이유는 다른 방법이 더 복잡하기 때문입니다. 예를 들면 :

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"

여기서 범위 대신 반복을 사용하는 것은 잘 알려진 함수가 아니기 때문에 덜 명확하고 가져와야하기 때문에 더 복잡합니다. 참조가 필요한 경우 주요 스타일 가이드는 PEP 20-The Zen of Python 및 PEP 8-Style Guide for Python Code입니다. 입니다.

또한 for range 버전은 언어 참조 및 tutorial 모두에서 사용되는 명시적인 예제 이지만이 경우 값이 사용됩니다. 이는 형식이 C 스타일 for 루프의 while 확장보다 더 친숙하다는 것을 의미합니다.


반복되는 것을 직접 사용하는 것이 낫지 for s in repeat('This is run 10 times', 10): print s않습니까?
— F1Rumors

확실히! 그러나 샘플 코드의 인쇄는 중앙 개체가 없을 수도있는 코드의 반복 된 부분의 예일뿐입니다.
— Yann Vernier

파이썬 핵심 개발자는이 빨리 사용하는 것보다 말한다 range() twitter.com/raymondh/status/1144527183341375488
— Chris_Rands

int매 반복마다 다른 객체 를 찾거나 만들 필요가 없기 때문에 실제로 더 빠릅니다 . 그러나 프로그래머 시간이 실행 ​​시간보다 더 중요 할 수 있습니다.
— Yann Vernier 19

2

루프 내에서 발생하는 부작용을 겪고 있다면 개인적으로 range()접근 방식을 선택 하겠습니다 .

루프 내에서 호출하는 함수의 결과에 관심이 있다면 목록 이해 또는 map접근 방식을 사용합니다. 이 같은:

def f(n):
    return n * n

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

결과 = (f for i in range (50))
— Luka Rahne

1
결과 = itertools.imap (f, range (50))
— Luka Rahne

@ralu, 결과에 대한 반복 또는 무작위 액세스가 필요하지 않은 경우에만.
— aaronasterling 2010

2
result = tuple (results) 튜플에 대한 슬라이싱이 O (1)이기 때문에 목록보다 훨씬 빠릅니다
— Luka Rahne

-3

어때요?

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

또는 더 못생긴 방식으로 :

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

또는 마지막으로보고 싶다면 :

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

어디:

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__()

-5

무언가를 반복하는 정말 비단뱀적인 방법은 없습니다. 그러나 더 나은 방법입니다.

map(lambda index:do_something(), xrange(10))

색인을 전달해야하는 경우 :

map(lambda index:do_something(index), xrange(10))

결과를 컬렉션으로 반환한다는 것을 고려하십시오. 따라서 결과를 수집해야하는 경우 도움이 될 수 있습니다.


이것은 실제로 더 좋지 않을뿐만 아니라 (함수 호출 오버 헤드, 덜 알려진 람다 식, 목록에서 사용되지 않는 결과 수집) 10은 반복 할 수 없습니다.
— Yann Vernier 2014

예, xrange (10) 10이 아닙니다. 함수를 작성하거나 루프를 만들 필요가 없기 때문에 더 낫다고 말했습니다. 그러나 내가 말했듯이 진짜 비단뱀적인 방법은 없습니다. 코드를 변경했습니다. 감사합니다.
— Abi M. Sangarab 2015
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.