Nach @wr. Beitrag, erhalte ich ähnliche Ergebnisse (für Python3.5)
from timeit import *
stats = ["for i in range(1000): next(iter(s))",
"for i in range(1000): \n\tfor x in s: \n\t\tbreak",
"for i in range(1000): s.add(s.pop())"]
for stat in stats:
t = Timer(stat, setup="s=set(range(100000))")
try:
print("Time for %s:\t %f"%(stat, t.timeit(number=1000)))
except:
t.print_exc()
Sortie :
Time for for i in range(1000): next(iter(s)): 0.205888
Time for for i in range(1000):
for x in s:
break: 0.083397
Time for for i in range(1000): s.add(s.pop()): 0.226570
Wenn jedoch die zugrunde liegende Menge geändert wird (z. B. durch Aufruf von remove()
) geht es bei den wiederholbaren Beispielen schlecht aus ( for
, iter
):
from timeit import *
stats = ["while s:\n\ta = next(iter(s))\n\ts.remove(a)",
"while s:\n\tfor x in s: break\n\ts.remove(x)",
"while s:\n\tx=s.pop()\n\ts.add(x)\n\ts.remove(x)"]
for stat in stats:
t = Timer(stat, setup="s=set(range(100000))")
try:
print("Time for %s:\t %f"%(stat, t.timeit(number=1000)))
except:
t.print_exc()
Ergebnisse in:
Time for while s:
a = next(iter(s))
s.remove(a): 2.938494
Time for while s:
for x in s: break
s.remove(x): 2.728367
Time for while s:
x=s.pop()
s.add(x)
s.remove(x): 0.030272
39 Stimmen
Weiß jemand, warum Python diese Funktion nicht bereits implementiert hat?
7 Stimmen
Was ist der Anwendungsfall? Set hat diese Fähigkeit aus einem bestimmten Grund nicht. Sie sollen durch sie iterieren und Set-bezogene Operationen durchführen wie
union
usw., ohne Elemente daraus zu entnehmen. Zum Beispielnext(iter({3,2,1}))
gibt immer zurück1
Wenn Sie also dachten, dass dies ein zufälliges Element zurückgeben würde - das stimmt nicht. Vielleicht verwenden Sie also einfach die falsche Datenstruktur? Was ist der Anwendungsfall?1 Stimmen
Verwandt: stackoverflow.com/questions/20625579/ (Ich weiß, es ist nicht dieselbe Frage, aber es gibt lohnende Alternativen und Einsichten).
1 Stimmen
@hlin117 Denn Set ist ein unsortierte Sammlung . Da keine Reihenfolge erwartet wird, macht es keinen Sinn, ein Element an einer bestimmten Position abzurufen - es wird erwartet, dass es zufällig ist.
2 Stimmen
@hlin117 Warum macht das dann keinen Sinn? Es heißt "Zeichnen mit Ersatz"...
0 Stimmen
Ich denke, das Problem ist, dass die Werte nicht nach dem Zufallsprinzip zurückgegeben werden und sie nicht den Eindruck erwecken wollen, dass dies der Fall ist. Wahrscheinlich wäre die echte Zufälligkeit ein zu großer Aufwand. Aber für Testzwecke wäre es dennoch einfach, einige
.get()
Funktion oder so...1 Stimmen
B = (a-set()).pop()
0 Stimmen
@Necho: I Liebe diese!!! Könnte man auch einfach machen:
set(a).pop()
?1 Stimmen
@DarenThomas Ich bin kein Experte für Python. Was ich weiß, ist, dass die Zeitkomplexität bei der Verwendung von set(a) O(len(a)) ist, also das Gleiche wie bei copy(). Im Falle der Differenz s-t ist die Zeitkomplexität O(len(t)), was in meinem Beispiel Null ist, aber vielleicht erzeugt die Operation (...).pop() intern eine Kopie, ich weiß es nicht. Das ist etwas, das uns ein Experte sagen könnte :)
4 Stimmen
Ein sinnvoller Anwendungsfall, auf den ich immer wieder stoße, ist dieser: Ich schreibe einen Test und erhalte eine Menge. Ich möchte jeden Wert darin betrachten, um weitere Daten für den Test zu erstellen. Es ist mir egal, welchen Wert ich erhalte, und es ist mir auch egal, ob es jedes Mal derselbe oder ein anderer ist. Ich brauche nur a Wert aus der Menge.