Absolut (für das von Ihnen angegebene Beispiel).
Tupel sind erstklassige Bürger in Python
Es gibt eine eingebaute Funktion divmod()
, die genau das tut.
q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == x
Es gibt andere Beispiele: 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()))
Übrigens sind Klammern meistens nicht erforderlich. Zitat aus der Python-Bibliothek Referenz :
Tupel können auf verschiedene Arten konstruiert werden:
- Verwenden Sie ein Paar Klammern, um das leere Tupel zu kennzeichnen: ()
- Verwenden eines nachgestellten Kommas für ein Singleton-Tupel: a oder (a,)
- Trennen von Elementen durch Kommas: a, b, c oder (a, b, c)
- Verwenden des integrierten tuple (): tuple () oder tuple (iterable)
Funktionen sollten einem einzigen Zweck dienen
Daher sollten sie ein einzelnes Objekt zurückgeben. In Ihrem Fall ist dieses Objekt ein Tupel. Betrachten Sie Tupel als eine zusammengesetzte Ad-hoc-Datenstruktur. Es gibt Sprachen, in denen fast jede einzelne Funktion mehrere Werte zurückgibt (Liste in Lisp).
Manchmal reicht es aus, (x, y)
statt zurückzukehren Point(x, y)
.
Benannte Tupel
Mit der Einführung benannter Tupel in Python 2.6 ist es in vielen Fällen vorzuziehen, benannte Tupel anstelle von einfachen Tupeln zurückzugeben.
>>> 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)
ist 6 mal langsamer als{'x': 10.5, 'y':11.5}
. Die absoluten Zeiten sind635 ns +- 26 ns
gegen105 ns +- 4 ns
. Es ist unwahrscheinlich, dass beides einen Engpass in der Anwendung darstellt. Optimieren Sie nicht, es sei denn, Ihr Profiler sagt etwas anderes. Erstellen Sie keine Klassen auf Funktionsebene, es sei denn, Sie wissen, warum Sie sie benötigen. Wenn Ihre API einedict
Verwendung erfordertdict
, hat dies nichts mit der Leistung zu tun.Beachten Sie zunächst, dass Python Folgendes zulässt (die Klammer ist nicht erforderlich):
In Bezug auf Ihre Frage gibt es keine feste Regel. Für einfache (und normalerweise erfundene) Beispiele scheint es immer möglich zu sein, dass eine bestimmte Funktion einen einzigen Zweck hat, was zu einem einzigen Wert führt. Wenn Sie Python jedoch für reale Anwendungen verwenden, stoßen Sie schnell auf viele Fälle, in denen die Rückgabe mehrerer Werte erforderlich ist, und führen zu saubererem Code.
Also würde ich sagen, mach was auch immer Sinn macht und versuche nicht, einer künstlichen Konvention zu entsprechen. Python unterstützt mehrere Rückgabewerte. Verwenden Sie diese daher gegebenenfalls.
quelle
q, r
ist ein Tupel.Das Beispiel, das Sie geben, ist eine in Python integrierte Funktion namens
divmod
. Irgendwann dachte jemand, es sei pythonisch genug, um es in die Kernfunktionalität aufzunehmen.Für mich ist es pythonisch, wenn es den Code sauberer macht. Vergleichen Sie diese beiden Codeblöcke:
quelle
Ja, die Rückgabe mehrerer Werte (dh eines Tupels) ist definitiv pythonisch. Wie andere bereits betont haben, gibt es in der Python-Standardbibliothek sowie in angesehenen Python-Projekten zahlreiche Beispiele. Zwei zusätzliche Kommentare:
Pythons Umgang mit Methodenargumenten erfordert die Fähigkeit, mehrere Werte direkt zurückzugeben. In C ++ können beispielsweise Methodenargumente als Referenz übergeben werden, sodass Sie ihnen zusätzlich zum formalen Rückgabewert Ausgabewerte zuweisen können. In Python werden Argumente "als Referenz" übergeben (jedoch im Sinne von Java, nicht von C ++). Sie können Methodenargumenten keine neuen Werte zuweisen und diese außerhalb des Methodenbereichs widerspiegeln. Beispielsweise:
Vergleichen mit:
quelle
Es ist definitiv pythonisch. Die Tatsache, dass Sie mehrere Werte von einer Funktion zurückgeben können, die Sie in einer Sprache wie C haben würden, in der Sie für jede Kombination von Typen, die Sie irgendwo zurückgeben, eine Struktur definieren müssen.
Wenn Sie jedoch den Punkt erreichen, an dem Sie etwas Verrücktes wie 10 Werte von einer einzelnen Funktion zurückgeben, sollten Sie ernsthaft in Betracht ziehen, sie in einer Klasse zu bündeln, da sie zu diesem Zeitpunkt unhandlich werden.
quelle
Ein Tupel zurückzugeben ist cool. Beachten Sie auch das neue Namedtuple, das in Python 2.6 hinzugefügt wurde und das für Sie möglicherweise schmackhafter wird: http://docs.python.org/dev/library/collections.html#collections.namedtuple
quelle
OT: Algol68 von RSRE hat den merkwürdigen Operator "/: =". z.B.
Geben Sie einen Quotienten von 3 und einen Rest von 16 an.
Hinweis: Normalerweise wird der Wert von "(x /: = y)" verworfen, da der Quotient "x" als Referenz zugewiesen wird. Im Fall von RSRE ist der zurückgegebene Wert der Rest.
vgl. Integer Arithmetic - Algol68
quelle
Es ist in Ordnung, mehrere Werte mit einem Tupel für einfache Funktionen wie z
divmod
. Wenn es den Code lesbar macht, ist es Pythonic.Wenn der Rückgabewert verwirrend wird, prüfen Sie, ob die Funktion zu viel leistet, und teilen Sie ihn gegebenenfalls auf. Wenn ein großes Tupel wie ein Objekt verwendet wird, machen Sie es zu einem Objekt. Erwägen Sie auch die Verwendung benannter Tupel , die Teil der Standardbibliothek in Python 2.6 sind.
quelle
Ich bin ziemlich neu in Python, aber die Tupel-Technik scheint mir sehr pythonisch. Ich hatte jedoch eine andere Idee, die die Lesbarkeit verbessern könnte. Die Verwendung eines Wörterbuchs ermöglicht den Zugriff auf die verschiedenen Werte nach Name und nicht nach Position. Beispielsweise:
quelle