어떤 언어든지간에 어떤 변수를 정해진 범위 내에서 한번씩 적용시켜가면서 반복 실행하는 구문은 필요하다. 파이썬에서는 for 구문으로 구현하고 정해진 범위를 리스트로 주도록 되어 있다.

예를 들어, C언어에서 for(i=0;i<10;i++)으로 주어진 반복문이라면 파이썬에서는 for i in range(0, 10) 으로 쓸 수 있다. 이때 주의해야 할 점은 range가 함수라는 부분이다. range(a, b, c)는 a부터 b까지 c칸씩 달리는 리스트를 되돌려 준다. c=1은 기본 사항이다.[각주:1]
http://docs.python.org/release/1.5.1p1/tut/range.html

그러나, 나에게 필요한 것은 for(i=0.0;i<1.0;i+=0.1)과 같은 구문이었고 파이썬에서 for i in range(0.0, 1.0, 0.1)은 나에게 좌절을 안겨주었다. range는 int에서만 잘 작동하는 함수였기 때문이다. 그래서 일단은 다음과 같은 코드를 작성해서 썼다.

x = 0.0
for i in range(0, 10):
    x=x+0.1
    function(x)

급한대로 이렇게 쓰긴 했는데, 이건 for구문이지만 while같다. 이럴거면 그냥 while을 쓰는게 낫지 싶은 느낌? 그래서 다른 방법들을 찾아보았다. 기본적으로는, 파이썬의 for문은 주어진 리스트 안의 변수들을 하나씩 순서대로 적용한다. 그럼 내가 원하는 대로 0.1씩 증가하는 리스트를 만들어서 주면 된다. 예를 들어
for i in [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]:
    function(x)

이렇게 쓰는 것은 의도한 대로 작동하는 구문이다. 물론 이건 10개니까 손으로 썼지만 100만개쯤 되면 손으로 쓰는건 컴퓨터 편하자고 사람이 고생하는 비극을 초래하므로 좀 더 멋진 방법을 찾아야 한다.

http://stackoverflow.com/questions/477486/python-decimal-range-step-value
http://code.activestate.com/recipes/66472/
몇가지 방법을 찾았는데, numpy에서 제공하는 arange 함수를 쓰는 방법이 있고, frange함수를 새로 정의하는 방법이 있다. 어떻든, 위에 쓴 0.0부터 1.0까지의 리스트를 제공하기만 하면 되고, 여러 사람들이 이 문제를 해결하고 있다.

그러다 보니, 문득 range함수를 오버로딩하면 안되는건가? 하는 생각이 들어서 검색해 보았다. 물론 이런 생각을 나만 하는건 아니었다.
http://ironboundsoftware.com/blog/2007/05/29/a-shortfall-of-python-no-function-overloading/
http://www.artima.com/weblogs/viewpost.jsp?thread=155514
귀도 반 로썸도 그런 생각을 했고, 2006년에 대충 구현을 해봤다고 하니 파이썬3에서는 잘 되지 않을까 싶었다. 그러나 그렇게 되지 않은 것 같다.
http://openlook.org:625/blog/2008/12/04/python3/
http://kldp.org/node/123275#comment-555572

아무튼, 일단 range 대신에 새로운 다른 함수로 정의해서 사용해야 한다는 점을 알게 되었다.
  1. 좀 더 정확히 쓰자면, for i in range(0, 10)이랑 같은 C언어 구문은 for(i=0;i<=10;i++)이다. [본문으로]
신고
by snowall 2011.07.10 07:43
  • solariser 2011.07.10 23:20 신고 ADDR EDIT/DEL REPLY

    당근 오버로딩 됩니다. (물론 언어차원에서 지원하지는 않습니다. 그렇다고 없다고 못박으면.. -_-)

    이런식으로 사용할 수 있습니다.
    snipt.org/xlRm

    • snowall 2011.07.11 00:23 신고 EDIT/DEL

      range는 그렇게 오버로딩이 되는데, 구현된거 보니까 오버로딩 자체를 구현했네요.

      그럼 다른 함수들 오버로딩도 그렇게 수동으로 해야 한다는 거네요...

      동적 타이핑 언어니까 어쩔 수 없긴 하지만, 저 구현을 사용자가 직접 정의해서 써야 한다는건 좀 불편하네요

    • snowall 2011.07.11 00:51 신고 EDIT/DEL

      아무튼 제가 느끼기에는 불편하네요. VB.net은 이런 점에서는 편하거든요. (*args,**kwargs)는 편하긴 하지만, 그건 사용하는 사람 입장에서고 만드는 입장에서는 삽질인듯 싶어요. (*args,**kwargs)를 지원하면서도 언어 수준의 자동화된 오버로드를 지원할 수는 없었는지 아쉽네요.

    • solariser 2011.07.11 00:53 신고 EDIT/DEL

      이게 묘한 장단점이 있습니다.

      단점은 역시 사람손으로 하니 "뭥미...-_-?"가 입에서 튀어나오는 상황이 오는거고...

      장점은 인자를 다루는 방법이 자유롭기 때문에(*args, **kwargs) 생각지도 못한 방법으로 오버로딩 할 수 있습니다. (별로 않좋은 건가.. -_-) c나 java의 varargs같은 흉칙한(?) 구현을 지양할 수 있습니다.

      추가적으로 사실 range의 구현은 잘못된 구현입니다. Duck Typing을 하는 파이썬의 특징을 무시한 구현입니다. (원래 Python 자체가 OOP로 출발한 언어가 아닐때 만들어졌고, 성능문제 때문에 int로 캐스팅해서 작동해서 그렇습니다.) range에 필요한 add, mul, gt, lt 의 method or attribute를 가지고 있으면 잘 동작해야 하는데 말입니다. 쩝...

  • combacsa 2011.07.11 03:34 신고 ADDR EDIT/DEL REPLY

    저라면 그냥

    for i in range(0, 10):
    function(x / 10.0)

    이렇게 하겠 (...)

  • combacsa 2013.08.28 03:31 신고 ADDR EDIT/DEL REPLY

    그러고보니 이렇게도 가능하네요.

    for i in map(lambda x: x / 10.0, xrange(0, 10)): function(i)

    • snowall 2013.08.28 03:35 신고 EDIT/DEL

      ㅋㅋㅋ 람다라니
      그러고보니 파이썬에서 람다를 써본적이 없군요
      아직 람다를 쓸만한 일이 나타나질 않네요