Gibt es ein Python-Äquivalent zu Ruby-Symbolen?
Wenn ja, was ist es dann?
Wenn nicht, müssen wir dann nur noch Strings als Schlüssel in Wörterbüchern verwenden?
Gibt es ein Python-Äquivalent zu Ruby-Symbolen?
Wenn ja, was ist es dann?
Wenn nicht, müssen wir dann nur noch Strings als Schlüssel in Wörterbüchern verwenden?
Antworten:
Nein, Python hat keinen Symboltyp.
Zeichenfolgenliterale werden jedoch standardmäßig interniert, und andere Zeichenfolgen können mithilfe der intern
Funktion interniert werden . Die Verwendung von String-Literalen als Schlüssel in Wörterbüchern ist also nicht weniger leistungsfähig als die Verwendung von Symbolen in Ruby.
Wie andere gesagt haben, gibt es in Python kein Symbol, aber Zeichenfolgen funktionieren gut.
Verwenden Sie die Konstruktorsyntax dict (), um das Zitieren von Zeichenfolgen als Schlüssel zu vermeiden:
d = dict(
a = 1,
b = 2,
c = "Hello there",
)
Auch für Interessierte: Symbole in Ruby, wenn sie in einem Hash verwendet werden, sind leeren Objekten in Python sehr ähnlich. Zum Beispiel könnten Sie tun:
some_var = object()
und setzen Sie dann einen Wörterbuchschlüssel als some_var:
some_dict = { some_var : 'some value' }
und dann einen Standardabruf durchführen:
some_dict[some_var]
Wie sepp2k jedoch feststellte, hat dies keinen Leistungsvorteil. Tatsächlich habe ich einen kurzen Test durchgeführt und wenig bis gar keine Leistungssteigerung festgestellt:
a, b, c, d, e = [object() for _ in range(5)]
dict_symbols = {a : 'a', b : 'b', c : 'c', d : 'd', e : 'e'}
dict_strings = {'a' : 'a', 'b' : 'b', 'c' : 'c', 'd' : 'd', 'e' : 'e'}
def run_symbols():
for key in dict_symbols.keys():
dict_symbols[key]
def run_strings():
for key in dict_strings.keys():
dict_strings[key]
Geschwindigkeit in Ipython getestet:
In [3]: %timeit run_symbols
10000000 loops, best of 3: 33.2 ns per loop
In [4]: %timeit run_strings
10000000 loops, best of 3: 28.3 ns per loop
In meinem Fall laufen die 'Symbole' also langsamer! (für lustige Zahlen, nicht genau). Es ist jedoch zu beachten, dass es auf diese Weise wahrscheinlich Speichervorteile gibt. Wenn Sie sich nicht für den Schlüsseltyp interessieren, haben Objekte eine geringere Stellfläche als Zeichenfolgen.
import sys
sys.getsizeof('some_var') # 45
some_var = object()
sys.getsizeof(some_var) # 0
Dies wirft jedoch die Frage auf, wie Python den Speicher des Variablennamens some_var behandelt.
k = "key"; d[k] = "value"
ist das dumm (aber nicht for k in keys: d[k] = "default"
, obwohl es bessere Möglichkeiten gibt), aber wie bereits gesagt, verwenden Sie die meiste Zeit Laufzeitwerte als Schlüssel.
Nicht als erstklassiger Typ, aber es gibt https://pypi.python.org/pypi/SymbolType .
d.b
anstattd['b']
, können Sie nur ein leeres verwendenclass D(object): pass
eine Instanz zu erstellen ,d = D()
auf die Sie dann Ihre Werte Attribute zuweisen können Sie machen, wie sod.a=1
undd.b=2
und Natürlich bekommen ihre Werte soprint(d.a + d.b)
. Ich bin mir nicht sicher, ob dies langsamer wäre als eine einfache Wörterbuchsuche wied['b']
in der Antwort.