programing tip

함수가 여러 값을 반환하는 것이 비단뱀입니까?

itbloger 2020. 10. 10. 09:41
반응형

함수가 여러 값을 반환하는 것이 비단뱀입니까?


파이썬에서는 함수가 여러 값을 반환하도록 할 수 있습니다. 다음은 인위적인 예입니다.

def divide(x, y):
    quotient = x/y
    remainder = x % y
    return quotient, remainder  

(q, r) = divide(22, 7)

이것은 매우 유용 해 보이지만 남용 될 수도 있습니다 ( "Well..function X는 이미 필요한 것을 중간 값으로 계산합니다. X도 그 값을 반환하도록합시다").

언제 선을 그리고 다른 방법을 정의해야합니까?


물론입니다 (제공 한 예의 경우).

튜플은 파이썬에서 일류 시민입니다.

divmod()정확히 그렇게 하는 내장 함수 가 있습니다.

q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == x

다른 예는 다음과 같습니다 zip, enumerate, dict.items.

for i, e in enumerate([1, 3, 3]):
    print "index=%d, element=%s" % (i, e)

# reverse keys and values in a dictionary
d = dict((v, k) for k, v in adict.items()) # or 
d = dict(zip(adict.values(), adict.keys()))

BTW, 괄호는 대부분 필요하지 않습니다. Python Library Reference 에서 인용 :

튜플은 여러 가지 방법으로 구성 할 수 있습니다.

  • 한 쌍의 괄호를 사용하여 빈 튜플 표시 : ()
  • 싱글 톤 튜플에 후행 쉼표 사용 : a 또는 (a,)
  • 쉼표로 항목 구분 : a, b, c 또는 (a, b, c)
  • 내장 tuple () 사용 : tuple () 또는 tuple (iterable)

기능은 단일 용도로 사용되어야합니다.

따라서 단일 객체를 반환해야합니다. 귀하의 경우이 객체는 튜플입니다. 튜플을 임시 복합 데이터 구조로 간주하십시오. 거의 모든 단일 함수가 여러 값을 반환하는 언어가 있습니다 (Lisp의 목록).

때로는 (x, y)대신 반환하는 것으로 충분합니다 Point(x, y).

명명 된 튜플

파이썬 2.6에 명명 된 튜플이 도입되면서 많은 경우 일반 튜플 대신 명명 된 튜플을 반환하는 것이 좋습니다.

>>> import collections
>>> Point = collections.namedtuple('Point', 'x y')
>>> x, y = Point(0, 1)
>>> p = Point(x, y)
>>> x, y, p
(0, 1, Point(x=0, y=1))
>>> p.x, p.y, p[0], p[1]
(0, 1, 0, 1)
>>> for i in p:
...   print(i)
...
0
1

첫째, Python은 다음을 허용합니다 (괄호가 필요 없음).

q, r = divide(22, 7)

귀하의 질문과 관련하여 어느 쪽이든 엄격하고 빠른 규칙은 없습니다. 간단한 (일반적으로 인위적인) 예제의 경우 주어진 함수가 항상 단일 목적을 가지고 단일 값을 생성 할 수있는 것처럼 보일 수 있습니다. 그러나 실제 응용 프로그램에 Python을 사용할 때 여러 값을 반환해야하는 많은 경우에 빠르게 실행되어 코드가 더 깔끔해집니다.

그래서, 나는 말이되는 것은 무엇이든하고, 인위적인 관습을 따르려고하지 마십시오. Python은 여러 반환 값을 지원하므로 적절할 때 사용하십시오.


당신이 제공하는 예제는 실제로라는 파이썬 내장 함수 divmod입니다. 그래서 누군가는 어느 시점에서 핵심 기능을 포함하기에 충분히 비단뱀이라고 생각했습니다.

나에게 코드를 깔끔하게 만든다면 비단뱀 적이다. 다음 두 코드 블록을 비교하십시오.

seconds = 1234
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)

seconds = 1234
minutes = seconds / 60
seconds = seconds % 60
hours = minutes / 60
minutes = minutes % 60

Yes, returning multiple values (i.e., a tuple) is definitely pythonic. As others have pointed out, there are plenty of examples in the Python standard library, as well as in well-respected Python projects. Two additional comments:

  1. Returning multiple values is sometimes very, very useful. Take, for example, a method that optionally handles an event (returning some value in doing so) and also returns success or failure. This might arise in a chain of responsibility pattern. In other cases, you want to return multiple, closely linked pieces of data---as in the example given. In this setting, returning multiple values is akin to returning a single instance of an anonymous class with several member variables.
  2. Python's handling of method arguments necessitates the ability to directly return multiple values. In C++, for example, method arguments can be passed by reference, so you can assign output values to them, in addition to the formal return value. In Python, arguments are passed "by reference" (but in the sense of Java, not C++). You can't assign new values to method arguments and have it reflected outside method scope. For example:

    // C++
    void test(int& arg)
    {
        arg = 1;
    }
    
    int foo = 0;
    test(foo); // foo is now 1!
    

    Compare with:

    # Python
    def test(arg):
        arg = 1
    
    foo = 0
    test(foo) # foo is still 0
    

It's definitely pythonic. The fact that you can return multiple values from a function the boilerplate you would have in a language like C where you need to define a struct for every combination of types you return somewhere.

However, if you reach the point where you are returning something crazy like 10 values from a single function, you should seriously consider bundling them in a class because at that point it gets unwieldy.


Returning a tuple is cool. Also note the new namedtuple which was added in python 2.6 which may make this more palatable for you: http://docs.python.org/dev/library/collections.html#collections.namedtuple


OT: RSRE's Algol68 has the curious "/:=" operator. eg.

INT quotient:=355, remainder;
remainder := (quotient /:= 113);

Giving a quotient of 3, and a remainder of 16.

Note: typically the value of "(x/:=y)" is discarded as quotient "x" is assigned by reference, but in RSRE's case the returned value is the remainder.

c.f. Integer Arithmetic - Algol68


It's fine to return multiple values using a tuple for simple functions such as divmod. If it makes the code readable, it's Pythonic.

If the return value starts to become confusing, check whether the function is doing too much and split it if it is. If a big tuple is being used like an object, make it an object. Also, consider using named tuples, which will be part of the standard library in Python 2.6.


I'm fairly new to Python, but the tuple technique seems very pythonic to me. However, I've had another idea that may enhance readability. Using a dictionary allows access to the different values by name rather than position. For example:

def divide(x, y):
    return {'quotient': x/y, 'remainder':x%y }

answer = divide(22, 7)
print answer['quotient']
print answer['remainder']

참고URL : https://stackoverflow.com/questions/61605/is-it-pythonic-for-a-function-to-return-multiple-values

반응형