Is there a Python equivalent to Ruby symbols?
Solution 1
No, python doesn't have a symbol type.
However string literals are interned by default and other strings can be interned using the intern
function. So using string literals as keys in dictionaries is not less performant than using symbols in ruby.
Solution 2
As others have said, there is no symbol in Python, but strings work well.
To avoid quoting strings as keys, use the dict() constructor syntax:
d = dict(
a = 1,
b = 2,
c = "Hello there",
)
Solution 3
Also for those interested: symbols in Ruby when used in a hash are very similar to empty objects in python. For example you could do:
some_var = object()
and then set a dictionary key as some_var:
some_dict = { some_var : 'some value' }
and then do a standard retrieval:
some_dict[some_var]
However, as sepp2k noted there is no performance benefit in doing this. In fact I did a quick test and noted little to no performance boost:
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]
Speed tested in ipython:
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
So in my case the 'symbols' run slower! (for fun numbers, not accurate). However it is to note that there are probably memory advantages to doing it this way. If you don't care about the key type objects have a smaller footprint than strings.
import sys
sys.getsizeof('some_var') # 45
some_var = object()
sys.getsizeof(some_var) # 0
Although that raises the question of how python treats the memory of the variable name some_var.
Solution 4
- No, there is no equivalent.
- No you can use every hashable object as dictionary key.
Solution 5
Not as a first-class type but there does exist https://pypi.python.org/pypi/SymbolType.
Related videos on Youtube
Comments
-
dreftymac over 4 years
Is there a Python equivalent to Ruby symbols?
If so then what is it?
If not then are we stuck with using strings as our keys in dictionaries only?
-
FriendFX about 11 yearsFollowing up on your comment to this answer below: If you want something where you can type
d.b
instead ofd['b']
, you could just use an emptyclass D(object): pass
to create an instanced = D()
to which you can then assign your values to attributes you make up, like sod.a=1
andd.b=2
and of course get their values like soprint(d.a + d.b)
. Not sure if that would be slower than a plain dictionary lookup like thed['b']
in the answer. -
Alexander Bird over 4 yearsAlso, if you want a unique constant whose data type is not a string, you can also use custom classes for that
-
wuputah over 13 years+1. Fortunately for us Ruby developers, performant is not a word. (Sorry, we're just so semantic!) :D
-
Glenn Maynard over 13 yearsThie major benefit of this is that the language has one less core syntax and builtin type. It's unnecessary complexity in the language when it can be done transparently.
-
Admin over 13 years@Glenn At first I was upset to hear that Python did not have symbols and that string literals can be used as keys. The problem is that I am not happy with the fact that I will have to place quotes around all my keys. Is there a way around this?
-
Admin over 13 yearsCan one assign a string literal to a variable and then use that variable as a key. e.g. orange = 'orange" food_type = {orange : 'fruit', banana : 'fruit'}
-
Admin over 13 years@J3M 7OR3: No, of course there's no way around this. But consider: It's just one additional character, and in real code, you often use varibles instead of literal keys anyway.
-
Admin over 13 years@J3M 7OR3: Strings are hashable! As are all immutable types. Concerning the second question... Python is not Javascript - keys in dict literals are not special. They can be any expression (a variable, a literal, ...), are evaluated and the result is used as key. So yes, this works.
-
Admin over 13 years@delnan Ok. But is using a variable, instead of a string literal, as a key best practice? Do people typically do this? Or are they fine with using just string literals ( with their quotes) as keys?
-
yantrab over 13 years@delnan, of course there is a way around this: dict(a=1,b=2,c=3).
-
aaronasterling over 13 yearsironically, this solution does, at least initially, restrict you to having strings as the keys.
-
Admin over 13 years@J3M 7OR3: Wat? Most of the time, you can't possibly know the key by the time you write the program. Of course
k = "key"; d[k] = "value"
is stupid (but notfor k in keys: d[k] = "default"
, although there are better ways), but as already said, most of the time you use runtime-values as keys. -
Admin over 13 yearsyeah, it is a work around but only during the assignment step. i still have to add quotes around the b in d['b'] to get its value. i guess i just remember ruby symbols being easier to type. i wish there was a module that solved this problem. i wonder if it would make the program run slower though.
-
Charles Roper over 10 yearsHere's a useful Q&A describing what intern does: stackoverflow.com/questions/1136826/…
-
Translunar over 8 yearsGreat answer! Thanks for looking into this.
-
TomDotTom over 6 yearsThe symbol = object() is probably closer to a Ruby Symbol than the above solution as this creates a unique object. foo = intern('foo) doesn't as foo == 'foo' would still be true.
-
Tiana over 2 years@pylonicon check out DotMap; it is a dict type that lets you access keys with dot-notation instead of the ugly["quoted_string_within_square_brackets"] thing