Это питон для функции, чтобы вернуть несколько значений?



в python функция может возвращать несколько значений. Вот надуманный пример:



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

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


это кажется очень полезным, но похоже, что им также можно злоупотреблять ("Ну..функция X уже вычисляет то, что нам нужно в качестве промежуточного значения. Пусть X также вернет это значение").



когда вы должны нарисовать линию и определить другой метод?

717   9  

9 ответов:

абсолютно (для примера вы указали).

кортежи являются гражданами первого класса в Python

есть встроенная функция 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()))

кстати, скобки не нужны большую часть времени. Цитата из Ссылка На Библиотеку Python:

кортежи могут быть построены в a количество способов:

  • используя пару скобок для обозначения пустого кортежа: ()
  • использование конечной запятой для одноэлементного кортежа: a, или (a,)
  • разделение элементов запятыми: a, b, c или (a, b, c)
  • С помощью кортежа () встроенный: кортеж () или кортеж(iterable)

функции должны служить одной цели

поэтому они должны возвращать один объект. В вашем случае этот объект это кортеж. Рассмотрим кортеж как специальную составную структуру данных. Есть языки, где почти каждая функция возвращает несколько значений (список в Лиспе).

иногда достаточно вернуться (x, y) вместо Point(x, y).

именованных кортежей

С введением именованных кортежей в Python 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 поддерживает несколько возвращаемых значений, поэтому использовать его при необходимости.

пример, который вы даете, на самом деле является встроенной функцией python, называемой divmod. Так что кто-то, в какой-то момент, казалось, что достаточно подходящие для Python, чтобы включить в базовую функциональность.

для меня, если это делает код чище, это питон. Сравните эти два блока кода:

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

да, возвращая несколько значений (т. е. кортеж), безусловно, питон. Как указывали другие, есть много примеров в стандартной библиотеке Python, а также в уважаемых проектах Python. Два дополнительных комментария:

  1. возврат нескольких значений иногда очень, очень полезно. Возьмем, например, метод, который необязательно обрабатывает событие (возвращая при этом некоторое значение), а также возвращает успех или неудачу. Это может возникнуть в цепочке модель ответственности. В других случаях вы хотите вернуть несколько тесно связанных фрагментов данных-как в приведенном примере. В этом параметре возврат нескольких значений сродни возвращению одного экземпляра анонимного класса с несколькими переменными-членами.
  2. обработка Python аргументов метода требует возможности прямого возврата нескольких значений. В C++, например, аргументы метода могут передаваться по ссылке, поэтому вы можете назначить им выходные значения, в добавление к формальному возвращаемому значению. В Python аргументы передаются "по ссылке" (но в смысле Java, а не C++). Вы не можете присвоить новые значения аргументам метода и отразить их вне области действия метода. Например:

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

    сравнить с:

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

Это определенно питон. Тот факт, что вы можете возвращать несколько значений из функции шаблонного шаблона, который у вас был бы на языке C, где вам нужно определить структуру для каждой комбинации типов, которые вы где-то возвращаете.

однако, если вы достигнете точки, где вы возвращаете что-то сумасшедшее, как 10 значений из одной функции, вы должны серьезно рассмотреть возможность объединения их в класс, потому что в этот момент он становится громоздким.

возвращение кортежа-это круто. Также обратите внимание на новый namedtuple который был добавлен в python 2.6, который может сделать это более приемлемым для вас: http://docs.python.org/dev/library/collections.html#collections.namedtuple

Я довольно новыми для Python, но техника кортежа, кажется, очень подходящие для Python для меня. Однако у меня была другая идея, которая может улучшить читаемость. Использование словаря позволяет получить доступ к различным значениям по имени, а не по позиции. Например:

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

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

OT: Algol68 RSRE имеет любопытный оператор"/:=". например.

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

дает частное 3 и остаток 16.

Примечание: обычно значение "(x/:=y) "отбрасывается как частное" x " назначается по ссылке, но в случае RSRE возвращаемое значение является остатком.

Си.Ф. Целочисленная Арифметика-Algol68

это нормально, чтобы вернуть несколько значений с помощью кортежа для простых функций, таких как divmod. Если это делает код читаемым, это питон.

Если возвращаемое значение начинает сбивать с толку, проверьте, не делает ли функция слишком много, и разделите его, если это так. Если большой кортеж используется как объект, сделайте его объектом. Кроме того, рассмотрите возможность использования именованных кортежей, который станет частью стандартной библиотеки в Python 2.6.

Comments

    Ничего не найдено.