Python: Retrieve items from a set

后端 未结 3 1407
执笔经年
执笔经年 2021-01-12 10:13

In general, Python sets don\'t seem to be designed for retrieving items by key. That\'s obviously what dictionaries are for. But is there anyway that, given a key, you can

3条回答
  •  灰色年华
    2021-01-12 10:54

    I'd definitely use a dictionary here. Reusing the firstname instance variable as a dictionary key won't copy it -- the dictionary will simply use the same object. I doubt a dictionary will use significantly more memory than a set.

    To actually save memory, add a __slots__ attribute to your classes. This will prevent each of you 10,000,000 instances from having a __dict__ attribute, which will save much more memory than the potential overhead of a dict over a set.

    Edit: Some numbers to back my claims. I defined a stupid example class storing pairs of random strings:

    def rand_str():
        return str.join("", (chr(random.randrange(97, 123))
                             for i in range(random.randrange(3, 16))))
    
    class A(object):
        def __init__(self):
            self.x = rand_str()
            self.y = rand_str()
        def __hash__(self):
            return hash(self.x)
        def __eq__(self, other):
            return self.x == other.x
    

    The amount of memory used by a set of 1,000,000 instances of this class

    random.seed(42)
    s = set(A() for i in xrange(1000000))
    

    is on my machine 240 MB. If I add

        __slots__ = ("x", "y")
    

    to the class, this goes down to 112 MB. If I store the same data in a dictionary

    def key_value():
        a = A()
        return a.x, a
    
    random.seed(42)
    d = dict(key_value() for i in xrange(1000000))
    

    this uses 249 MB without __slots__ and 121 MB with __slots__.

提交回复
热议问题