Why dict.get(key) instead of dict[key]?

后端 未结 10 2485
生来不讨喜
生来不讨喜 2020-11-21 05:51

Today, I came across the dict method get which, given a key in the dictionary, returns the associated value.

For what purpose is this funct

10条回答
  •  南笙
    南笙 (楼主)
    2020-11-21 06:19

    What is the dict.get() method?

    As already mentioned the get method contains an additional parameter which indicates the missing value. From the documentation

    get(key[, default])
    

    Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

    An example can be

    >>> d = {1:2,2:3}
    >>> d[1]
    2
    >>> d.get(1)
    2
    >>> d.get(3)
    >>> repr(d.get(3))
    'None'
    >>> d.get(3,1)
    1
    

    Are there speed improvements anywhere?

    As mentioned here,

    It seems that all three approaches now exhibit similar performance (within about 10% of each other), more or less independent of the properties of the list of words.

    Earlier get was considerably slower, However now the speed is almost comparable along with the additional advantage of returning the default value. But to clear all our queries, we can test on a fairly large list (Note that the test includes looking up all the valid keys only)

    def getway(d):
        for i in range(100):
            s = d.get(i)
    
    def lookup(d):
        for i in range(100):
            s = d[i]
    

    Now timing these two functions using timeit

    >>> import timeit
    >>> print(timeit.timeit("getway({i:i for i in range(100)})","from __main__ import getway"))
    20.2124660015
    >>> print(timeit.timeit("lookup({i:i for i in range(100)})","from __main__ import lookup"))
    16.16223979
    

    As we can see the lookup is faster than the get as there is no function lookup. This can be seen through dis

    >>> def lookup(d,val):
    ...     return d[val]
    ... 
    >>> def getway(d,val):
    ...     return d.get(val)
    ... 
    >>> dis.dis(getway)
      2           0 LOAD_FAST                0 (d)
                  3 LOAD_ATTR                0 (get)
                  6 LOAD_FAST                1 (val)
                  9 CALL_FUNCTION            1
                 12 RETURN_VALUE        
    >>> dis.dis(lookup)
      2           0 LOAD_FAST                0 (d)
                  3 LOAD_FAST                1 (val)
                  6 BINARY_SUBSCR       
                  7 RETURN_VALUE  
    

    Where will it be useful?

    It will be useful whenever you want to provide a default value whenever you are looking up a dictionary. This reduces

     if key in dic:
          val = dic[key]
     else:
          val = def_val
    

    To a single line, val = dic.get(key,def_val)

    Where will it be NOT useful?

    Whenever you want to return a KeyError stating that the particular key is not available. Returning a default value also carries the risk that a particular default value may be a key too!

    Is it possible to have get like feature in dict['key']?

    Yes! We need to implement the __missing__ in a dict subclass.

    A sample program can be

    class MyDict(dict):
        def __missing__(self, key):
            return None
    

    A small demonstration can be

    >>> my_d = MyDict({1:2,2:3})
    >>> my_d[1]
    2
    >>> my_d[3]
    >>> repr(my_d[3])
    'None'
    

提交回复
热议问题