Абсолютно (для примера Вы обеспечили).
существует встроенная функция 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, круглые скобки не необходимы большую часть времени. Цитата от [1 110] Справочное руководство по библиотеке Python:
Кортежи могут быть созданы различными способами:
- Используя пару круглых скобок для обозначения пустого кортежа: ()
- Используя запаздывающую запятую для одноэлементного кортежа: a или (a),
- Разделение объектов с запятыми: a, b, c или (a, b, c)
- Используя кортеж () встроенный: кортеж () или кортеж (повторяемый)
Поэтому, они должны возвратить отдельный объект. В Вашем случае этот объект является кортежем. Рассмотрите кортеж как специальную составную структуру данных. Существуют языки, куда почти каждая функция возвращает несколько значений (список в Lisp).
Иногда достаточно возвратиться (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
. Таким образом, кто-то, в какой-то момент вовремя, думал, что это был pythonic достаточно для включения в базовую функциональность.
мне, если это делает инструмент для очистки кода, это - pythonic. Сравните эти два блока кода:
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
Это определенно pythonic. То, что можно возвратить несколько значений из функции шаблон, который Вы имели бы на языке как C, где необходимо определить структуру для каждой комбинации типов, Вы возвращаетесь куда-нибудь.
Однако, если Вы достигаете точки, куда Вы возвращаете что-то сумасшедшее как 10 значений от единственной функции, необходимо серьезно рассмотреть связывание их в классе, потому что в той точке это становится громоздким.
Да, возврат нескольких значений (т.е. кортеж) определенно pythonic. Как другие указали, существует много примеров в библиотеке стандарта Python, а также в хорошо уважаемых проектах Python. Два дополнительных комментария:
обработка 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
OT: Algol68 RSRE имеет любопытное "/: =" оператор. например,
INT quotient:=355, remainder;
remainder := (quotient /:= 113);
Предоставление частного 3 и остатка от 16.
Примечание: обычно значение" (x/: = y)" отбрасывается, поскольку частное "x" присвоено ссылкой, но в случае RSRE возвращенное значение является остатком.
Возврат кортежа прохладен. Также отметьте новый namedtuple, который был добавлен в python 2.6, который может сделать это более приемлемым для Вас: http://docs.python.org/dev/library/collections.html#collections.namedtuple
Хорошо возвращать несколько значений с помощью кортежа для простых функций такой как divmod
. Если это делает код читаемым, это - Pythonic.
, Если возвращаемое значение начинает становиться сбивающим с толку, проверьте, делает ли функция слишком много и разделила его, если это. Если большой кортеж используется как объект, сделайте его объектом. Кроме того, рассмотрите использование именованные кортежи , который будет частью стандартной библиотеки в Python 2.6.
Я довольно плохо знаком с Python, но метод кортежа кажется очень pythonic мне. Однако у меня была другая идея, которая может улучшить удобочитаемость. Используя словарь предоставляет доступ к различным значениям по имени, а не положению. Например:
def divide(x, y):
return {'quotient': x/y, 'remainder':x%y }
answer = divide(22, 7)
print answer['quotient']
print answer['remainder']