2010-09-18 5 views
60

Gibt es ein Python-Äquivalent zu Ruby-Symbolen?Gibt es ein Python-Äquivalent zu Ruby-Symbolen?

  • Wenn ja, was ist das?

  • Wenn nicht, dann werden wir nur mit der Verwendung von Saiten als unsere Schlüssel in Wörterbücher stecken?

+3

Verfolgen Sie Ihren Kommentar zu [dieser Antwort unten] (http://stackoverflow.com/a/3743919/897968): Wenn Sie etwas wollen, wo Sie 'db' anstelle von' d ['b'] eingeben können ', könnten Sie einfach eine leere' Klasse D (Objekt): pass 'verwenden, um eine Instanz 'd = D()' zu erstellen, der Sie dann Ihre Werte den Attributen zuweisen können, die Sie bilden, wie zB 'd.a = 1' und 'd.b = 2' und natürlich ihre Werte wie' print (d.a + d.b) '. Ich bin mir nicht sicher, ob das langsamer wäre als eine einfache Wörterbuchsuche wie das 'd ['b']' in der Antwort. – FriendFX

Antwort

66

Nein, Python hat keinen Symboltyp.

Allerdings sind String-Literale standardmäßig interniert und andere Strings können mit der intern-Funktion interniert werden. Daher ist die Verwendung von String-Literalen als Schlüssel in Wörterbüchern nicht weniger performant als die Verwendung von Symbolen in Ruby.

+11

+1. Glücklicherweise für uns Ruby-Entwickler, p erformant ist kein Wort. (Sorry, wir sind nur so semantisch!): D – wuputah

+7

Der Hauptvorteil davon ist, dass die Sprache eine Kern-Syntax und einen eingebauten Typ hat. Es ist unnötige Komplexität in der Sprache, wenn es transparent gemacht werden kann. –

+0

@Glenn Zuerst war ich verärgert zu hören, dass Python keine Symbole hat und dass String-Literale als Schlüssel verwendet werden können. Das Problem ist, dass ich nicht glücklich bin mit der Tatsache, dass ich alle meine Schlüssel in Anführungszeichen setzen muss. Gibt es einen Weg dahin? –

6
  1. Nein, es gibt kein Äquivalent.
  2. Nein, Sie können jedes hashbare Objekt als Wörterbuchschlüssel verwenden.
+0

Kann man einer Variablen ein String-Literal zuweisen und diese Variable dann als Schlüssel verwenden? z.B. orange = 'orange' food_type = {Orange: 'Frucht', Banane: 'Frucht'} –

+0

@ J3M 7OR3: Strings sind hashbar! Wie alle unveränderlichen Typen. In Bezug auf die zweite Frage ... Python ist nicht Javascript - Schlüssel in dict Literale sind nicht besonders, sie können beliebige Ausdrücke sein (eine Variable, ein Literal, ...), ausgewertet werden und das Ergebnis wird als Schlüssel verwendet. Also ja, das funktioniert. – delnan

+0

@delnan Ok. Aber verwendet stattdessen eine Variable eines Zeichenkettenliterals, als eine Schlüssel-Best Practice? Tun Menschen in der Regel dies? Oder sind sie in Ordnung mit nur String-Literale (mit ihren Anführungszeichen) als Schlüssel? –

15

Wie andere gesagt haben, gibt es in Python kein Symbol, aber Strings funktionieren gut.

Um zu vermeiden, Strings als Schlüssel zu zitieren, verwenden Sie die dict() Konstruktor Syntax:

d = dict(
    a = 1, 
    b = 2, 
    c = "Hello there", 
    ) 
+1

ironisch, diese Lösung _does_, zumindest anfangs, beschränken Sie auf Zeichenfolgen als Schlüssel. – aaronasterling

+0

Ja, es ist eine Arbeit, aber nur während des Zuweisungsschritts. Ich muss immer noch Zitate um das b in d ['b'] hinzufügen, um seinen Wert zu erhalten. Ich denke, ich erinnere mich nur an Ruby-Symbole, die einfacher zu tippen sind. Ich wünschte, es gäbe ein Modul, das dieses Problem gelöst hat. Ich frage mich, ob es das Programm langsamer laufen lassen würde. –

8

Auch für Interessierte: Symbole in Ruby, wenn sie in einem Hash verwendet werden, sind den leeren Objekten in Python sehr ähnlich. Zum Beispiel könnten Sie tun:

some_var = object() 

und legen Sie dann ein Wörterbuch Schlüssel als some_var:

some_dict = { some_var : 'some value' } 

und machen dann eine Standard-Retrieval:

some_dict[some_var] 

jedoch als sepp2k dort festgestellt ist kein Leistungsvorteil dabei. In der Tat habe ich einen schnellen Test und stellte fest, wenig bis gar keine Leistungssteigerung:

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 

Also in meinem Fall die 'Symbole' langsamer läuft! (für lustige Zahlen, nicht genau). Es ist jedoch anzumerken, dass es wahrscheinlich Speichervorteile gibt, dies auf diese Weise zu tun. Wenn Sie sich nicht um den Schlüsseltyp kümmern, haben Objekte einen kleineren Platzbedarf als Strings.

import sys 
sys.getsizeof('some_var') # 45 
some_var = object() 
sys.getsizeof(some_var) # 0 

Obwohl, dass die Frage, wie Python behandelt die Erinnerung an den Variablennamen some_var erhöht.

+0

Große Antwort! Danke, dass du dir das angeschaut hast. –