Komplexität des Operators * in * in Python

78

Was ist die Komplexität des inOperators in Python? Ist es Theta (n)?

Ist es dasselbe wie das Folgende?

def find(L, x):
   for e in L:
       if e == x:
           return True
   return False

L ist eine Liste.

Sajad Rastegar
quelle
3
Dies hängt von der Art des Containers ab, da die Verwendung mit einem Wörterbuch oder einem Set viel schneller ist als mit einem Array.
Greg Hewgill
1
@BasicWolf Ich habe L verwendet, also ist es Liste
Sajad Rastegar
5
@ Rastegar Limpliziert keine Liste. seqist die häufigste Wahl, wenn man eine Liste implizieren möchte. List ein schrecklicher Variablenname. Einzelbuchstaben sind schlecht, und das Kapital impliziert, dass es eine Klasse ist. Auch wenn es sich um etwas Besonderes handelte, ist Python dynamisch. Geben Sie dies in einem solchen Fall explizit an.
Gareth Latty
1
Lbedeutet list? Meine libtelepathy.so ist wahrscheinlich veraltet.
Zaur Nasibov
1
@GarethLatty Die Verwendung von lst ist auch ein guter Name, um alist
r0ei

Antworten:

136

Die Komplexität von inhängt ganz davon ab, was List. e in Lwird werden L.__contains__(e).

In diesem Dokument zur Zeitkomplexität finden Sie Informationen zur Komplexität mehrerer integrierter Typen.

Hier ist die Zusammenfassung für in:

  • Liste - Durchschnitt: O (n)
  • set / dict - Durchschnitt: O (1), Worst: O (n)

Der O (n) Worst Case für Sets und Dicts ist sehr ungewöhnlich, kann aber passieren, wenn er __hash__schlecht implementiert wird. Dies geschieht nur, wenn alles in Ihrem Set den gleichen Hashwert hat.

Andrew Clark
quelle
1
Kennt jemand zufällig die Komplexität des "in" -Operators für ein OrderedDict?
Josh Sherick
1
Nach einigen Tests kann ich bestätigen, dass die Komplexität von OrderedDict in Python 2.7 im Durchschnitt O (1) zu sein scheint.
Josh Sherick
@Josh Sherick Sie müssen keine Tests bereitstellen, alles, was Sie brauchen, sind die Quellen der OrderedDict, und wie Sie herausfinden konnten: OrderedDictwird von geerbt dict, so dass die meisten Operationen (natürlich mit Ausnahmen) die gleiche Komplexität haben .
Maxkoryukov
Ist die zeitliche Komplexität des "in" -Operators O (n) auch für Tupel?
Inherited Geek
Was ist die zeitliche Komplexität des "in" -Operators bei Verwendung mit einem Generator?
Mit dem
12

Dies hängt vollständig von der Art des Behälters ab. Hashing-Container ( dict, set) verwenden den Hash und sind im Wesentlichen O (1). Typische Sequenzen ( list, tuple) werden wie erraten implementiert und sind O (n). Bäume wären durchschnittlich O (log n). Und so weiter. Jeder dieser Typen hätte eine geeignete __contains__Methode mit seinen Big-O-Eigenschaften.

irgendwie
quelle
Der Wert umfasst den Aufwand für die Generierung des Hash.
Woot4Moo
Hashing Datentypen umfassen dictund set(sowie möglicherweise andere)
Dave
1
@ Woot4Moo: Wenn Sie über asymptotische Komplexität sprechen, ist das nicht relevant. Der Aufwand für die Generierung des Hash ist konstant. Wenn Sie mit kleinen Werten von N arbeiten, wird die Profilerstellung wichtig, z. B. 100 >> 2N für kleine N. Dies ist jedoch ein anderes Problem als das, worüber das OP gefragt hat. für riesiges N 100 << 2N, worum es bei Komplexität geht.
Abarnert
@abarnert gut, es ist tatsächlich ziemlich relevant, da Sie Datenstrukturen nicht willkürlich auswählen. Sie müssen die Verwendung und die gängigsten Verwendungsarten der Struktur berücksichtigen. Daher ist es wichtig, die Zeitdauer für eine Hash-Funktion zu berücksichtigen, insbesondere in einem Szenario, in dem die Has pro Iteration eines Programms berechnet werden muss.
Woot4Moo
@ Woot4Moo: Wenn jemand nach asymptotischer Komplexität fragt, (a) erwartet er, mit einem großen N umzugehen, oder (b) ist er ein Idiot. Ich gehe davon aus, dass das OP Fall (a) ist, aber in beiden Fällen ist der konstante Faktor für die Antwort nicht relevant.
Abarnert
-1

Dies hängt vom zu testenden Container ab. Es ist normalerweise das, was Sie erwarten würden - linear für geordnete Datenstrukturen, konstant für ungeordnete. Natürlich gibt es beide Typen (geordnet oder ungeordnet), die möglicherweise von einer Baumvariante unterstützt werden.

Marcin
quelle
@ZoranPavlovic A in Btestet, ob Ain B.
Marcin
1
Ich würde definitiv eine logarithmische Zeit in einer geordneten Struktur erwarten.
dedObed
@dedObed Warum würdest du das erwarten? Erwarten Sie, dass Python bereits weiß, ob Ihre Daten sortiert sind oder nicht?
Marcin
Denn wenn es einen Container gibt, der bestellt werden soll, besteht der offensichtliche Grund darin, logarithmische Suchvorgänge zuzulassen. Aber ich denke, es ist nur ein Namensproblem, ich würde "linear" verwenden, wo Sie "bestellt" geschrieben haben, und alles wäre in Ordnung. (In meinem Kopf - Englisch als zweite Sprache hier.)
dedObed