Absolutnie (na przykład podany przez Ciebie).
Krotki są obywatelami pierwszej klasy w Pythonie
Jest wbudowana funkcja divmod()
, która dokładnie to robi.
q, r = divmod(x, y)
Są też inne przykłady: zip
, enumerate
, dict.items
.
for i, e in enumerate([1, 3, 3]):
print "index=%d, element=%s" % (i, e)
d = dict((v, k) for k, v in adict.items())
d = dict(zip(adict.values(), adict.keys()))
Przy okazji, nawiasy nie są potrzebne przez większość czasu. Cytat z Python Library Reference :
Krotki można konstruować na wiele sposobów:
- Używanie pary nawiasów do oznaczenia pustej krotki: ()
- Używanie końcowego przecinka dla krotki pojedynczej: a lub (a,)
- Oddzielanie elementów przecinkami: a, b, c lub (a, b, c)
- Korzystanie z wbudowanej tuple (): tuple () lub tuple (iterable)
Funkcje powinny służyć jednemu celowi
Dlatego powinny zwrócić pojedynczy obiekt. W twoim przypadku ten obiekt jest krotką. Traktuj krotkę jako złożoną strukturę danych ad hoc. Istnieją języki, w których prawie każda funkcja zwraca wiele wartości (lista w Lisp).
Czasami wystarczy wrócić (x, y)
zamiast Point(x, y)
.
Nazwane krotki
Wraz z wprowadzeniem nazwanych krotek w Pythonie 2.6 w wielu przypadkach preferuje się zwracanie nazwanych krotek zamiast zwykłych krotek.
>>> 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
Point(10.5, 11.5)
jest 6 razy wolniejsze niż{'x': 10.5, 'y':11.5}
. Absolutne czasy635 ns +- 26 ns
porównaniu105 ns +- 4 ns
. Jest mało prawdopodobne, że którykolwiek z nich stanowiłby wąskie gardło w aplikacji - nie optymalizuj, chyba że profiler mówi inaczej. Nie twórz klas na poziomie funkcji, chyba że wiesz, dlaczego tego potrzebujesz. Jeśli twoje API wymagadict
niż używaniadict
- nie ma to nic wspólnego z wydajnością.Po pierwsze, zauważ, że Python pozwala na następujące rzeczy (nie ma potrzeby stosowania nawiasów):
q, r = divide(22, 7)
Jeśli chodzi o twoje pytanie, tak czy inaczej nie ma sztywnej i szybkiej reguły. W przypadku prostych (i zwykle wymyślonych) przykładów może się wydawać, że zawsze jest możliwe, aby dana funkcja miała jeden cel, co daje jedną wartość. Jednak podczas korzystania z języka Python w rzeczywistych aplikacjach szybko napotykasz wiele przypadków, w których konieczne jest zwrócenie wielu wartości, co skutkuje czystszym kodem.
Więc powiedziałbym, rób wszystko, co ma sens i nie próbuj dostosowywać się do sztucznej konwencji. Python obsługuje wiele zwracanych wartości, więc używaj go w razie potrzeby.
źródło
q, r
jest krotką.Podany przykład to w rzeczywistości wbudowana funkcja Pythona o nazwie
divmod
. Ktoś więc w pewnym momencie pomyślał, że jest wystarczająco pythonowy, aby uwzględnić podstawową funkcjonalność.Dla mnie, jeśli sprawia, że kod jest czystszy, to jest Python. Porównaj te dwa bloki kodu:
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
źródło
Tak, zwracanie wielu wartości (np. Krotki) jest zdecydowanie pythonowe. Jak zauważyli inni, istnieje wiele przykładów w standardowej bibliotece Pythona, a także w szanowanych projektach Pythona. Dwie dodatkowe uwagi:
Obsługa argumentów metod w Pythonie wymaga możliwości bezpośredniego zwracania wielu wartości. Na przykład w C ++ argumenty metody mogą być przekazywane przez odwołanie, dzięki czemu można przypisać im wartości wyjściowe oprócz formalnej wartości zwracanej. W Pythonie argumenty są przekazywane „przez referencję” (ale w sensie Javy, a nie C ++). Nie można przypisać nowych wartości do argumentów metody i mieć odzwierciedlenie poza zakresem metody. Na przykład:
// C++ void test(int& arg) { arg = 1; } int foo = 0; test(foo); // foo is now 1!
Porównać z:
# Python def test(arg): arg = 1 foo = 0 test(foo) # foo is still 0
źródło
To zdecydowanie pytoniczne. Fakt, że możesz zwrócić wiele wartości z funkcji, która jest szablonem, który miałbyś w języku takim jak C, w którym musisz zdefiniować strukturę dla każdej kombinacji typów, które gdzieś zwracasz.
Jeśli jednak osiągniesz punkt, w którym zwracasz coś szalonego, na przykład 10 wartości z jednej funkcji, powinieneś poważnie rozważyć umieszczenie ich w klasie, ponieważ w tym momencie staje się nieporęczna.
źródło
Zwracanie krotki jest super. Zwróć także uwagę na nową nazwę namedtuple, która została dodana w pythonie 2.6, która może sprawić, że będzie to dla Ciebie przyjemniejsze: http://docs.python.org/dev/library/collections.html#collections.namedtuple
źródło
OT: Algol68 RSRE ma ciekawy operator "/: =". na przykład.
INT quotient:=355, remainder; remainder := (quotient /:= 113);
Dając iloraz 3 i resztę 16.
Uwaga: zazwyczaj wartość „(x /: = y)” jest odrzucana, ponieważ iloraz „x” jest przypisywany przez odniesienie, ale w przypadku RSRE zwracaną wartością jest reszta.
cf Arytmetyka liczb całkowitych - Algol68
źródło
Zwracanie wielu wartości przy użyciu krotki w przypadku prostych funkcji, takich jak
divmod
. Jeśli sprawia, że kod jest czytelny, jest to Pythonic.Jeśli zwracana wartość zaczyna być myląca, sprawdź, czy funkcja nie robi za dużo i podziel ją, jeśli tak jest. Jeśli duża krotka jest używana jak obiekt, uczyń ją obiektem. Rozważ również użycie nazwanych krotek , które będą częścią standardowej biblioteki w Pythonie 2.6.
źródło
Jestem całkiem nowy w Pythonie, ale technika krotki wydaje mi się bardzo pytoniczna. Jednak mam inny pomysł, który może poprawić czytelność. Korzystanie ze słownika umożliwia dostęp do różnych wartości według nazwy, a nie pozycji. Na przykład:
def divide(x, y): return {'quotient': x/y, 'remainder':x%y } answer = divide(22, 7) print answer['quotient'] print answer['remainder']
źródło