36

Instead of this:

a = {"foo": None, "bar": None}

Is there a way to write this?

b = {"foo", "bar"}

And still let b have constant time access (i.e. not a Python set, which cannot be keyed into)?

nucleartide
  • 3,888
  • 4
  • 28
  • 29

3 Answers3

34

Actually, in Python 2.7 and 3.2+, this really does work:

>>> b = {"foo", "bar"}
>>> b
set(['foo', 'bar'])

You can't use [] access on a set ("key into"), but you can test for inclusion:

>>> 'x' in b
False
>>> 'foo' in b
True

Sets are as close to value-less dictionaries as it gets. They have average-case constant-time access, require hashable objects (i.e. no storing lists or dicts in sets), and even support their own comprehension syntax:

{x**2 for x in xrange(100)}
nneonneo
  • 171,345
  • 36
  • 312
  • 383
20

Yes, sets:

set() -> new empty set object
set(iterable) -> new set object

Build an unordered collection of unique elements.

Related: How is set() implemented?

Time complexity : https://wiki.python.org/moin/TimeComplexity#set

Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
4

In order to "key" into a set in constant time use in:

>>> s = set(['foo', 'bar', 'baz'])
>>> 'foo' in s
True
>>> 'fork' in s
False
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • 1
    This might slightly confusing. `"a"` is in the set because `set("abcd")` treated the string as an iterable of four characters. `set("abcd")` is the same as `set(['a', 'c', 'b', 'd'])`. So while `"fork"` definitely isn't in the set, neither is `"abcd"`, which this answer could imply. – poulter7 Feb 18 '15 at 16:23
  • 1
    `set(['foo', 'bar', 'baz')` should be `set(['foo', 'bar', 'baz'])`, this is clearer though :) – poulter7 Feb 23 '15 at 22:24