509 Stimmen

Warum gibt es keine Tupel-Komprehension in Python?

Wie wir alle wissen, gibt es Listenverständnis, wie z.B.

[i for i in [1, 2, 3, 4]]

und es gibt Wörterbuchverständnis, wie z.B.

{i:j for i, j in {1: 'a', 2: 'b'}.items()}

aber

(i for i in (1, 2, 3))

wird letztendlich in einen Generator umgewandelt, nicht in eine tuple-Verständnis. Warum ist das so?

Meine Vermutung ist, dass ein tuple unveränderlich ist, aber das scheint nicht die Antwort zu sein.

742voto

Martijn Pieters Punkte 953257

Sie können einen Generatorausdruck verwenden:

tuple(i for i in (1, 2, 3))

aber Klammern wurden bereits für … Generatorausdrücke verwendet.

104voto

chepner Punkte 440093

Raymond Hettinger (einer der Python-Kernentwickler) hatte dies über Tupel in einem kürzlichen Tweet zu sagen:

python Tipp: Im Allgemeinen sind Listen zum Durchlaufen gedacht; Tupel für Strukturen. Listen sind homogen; Tupel heterogen. Listen für variabler Länge.

Dies unterstützt meiner Meinung nach die Idee, dass, wenn die Elemente in einer Sequenz ausreichend zusammenhängen, um von einem, nun ja, Generator erstellt zu werden, es sich um eine Liste handeln sollte. Obwohl ein Tupel iterierbar ist und wie eine unveränderliche Liste erscheint, ist es wirklich das Python-Äquivalent einer C-Struktur:

struct {
    int a;
    char b;
    float c;
} foo;

struct foo x = { 3, 'g', 5.9 };

wird in Python zu

x = (3, 'g', 5.9)

101voto

czheo Punkte 1662

Seit Python 3.5 kannst du auch die Splat-*-Unpacking-Syntax verwenden, um einen Generatorausdruck zu entpacken:

*(x for x in range(10)),

72voto

Tom Punkte 829

Wie ein weiterer Poster macm in seiner Antwort erwähnt hat, ist der schnellste Weg, ein Tupel aus einem Generator zu erstellen, tuple([generator]).


Leistungsvergleich

  • List Comprehension:

      $ python3 -m timeit "a = [i for i in range(1000)]"
      10000 loops, best of 3: 27.4 usec per loop
  • Tupel aus List Comprehension:

      $ python3 -m timeit "a = tuple([i for i in range(1000)])"
      10000 loops, best of 3: 30.2 usec per loop
  • Tupel aus Generator:

      $ python3 -m timeit "a = tuple(i for i in range(1000))"
      10000 loops, best of 3: 50.4 usec per loop
  • Tupel aus Entpacken:

      $ python3 -m timeit "a = *(i for i in range(1000)),"
      10000 loops, best of 3: 52.7 usec per loop

Meine Version von Python:

$ python3 --version
Python 3.6.3

Sie sollten also immer ein Tupel aus einer List Comprehension erstellen, es sei denn, die Leistung ist kein Problem.

37voto

Inbar Rose Punkte 39054

Verständnis funktioniert durch Schleifen oder Iterieren über Elemente und Zuweisen von ihnen in einen Container, ein Tupel kann keine Zuweisungen erhalten.

Sobald ein Tupel erstellt wurde, kann es nicht angehängt, erweitert oder zugewiesen werden. Der einzige Weg, ein Tupel zu ändern, besteht darin, wenn eines seiner Objekte selbst zugewiesen werden kann (ist ein Nicht-Tupel-Container). Denn das Tupel hält nur eine Referenz auf diese Art von Objekt.

Außerdem - ein Tupel hat seinen eigenen Konstruktor tuple(), dem Sie einen beliebigen Iterator geben können. Das bedeutet, dass Sie ein Tupel erstellen können, indem Sie Folgendes tun:

tuple(i for i in (1,2,3))

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X