Search code examples
pythonpython-2.7python-3.xdefaultdict

Python 3 defaultdict with lambda expression


I have a code that was working in python 2, but now in python 3 raises the error "TypeError: keyword arguments must be strings". It is the first line of a function, so shouldn't be a problem with previous code.

   map = collections.defaultdict(lambda: 'blinn',**{0: 'constant', 1:'lambert'})

Maybe someone could also explain me what this line of code is doing and what is the "map" object that creates. I have found Python defaultdict and lambda but I still have problems in understanding this line of code.


Solution

  • The **{0: 'constant', 1:'lambert'} passes in two default key-value pairs as keyword arguments to the defaultdict() constructor. However, the same constructor would treat a dictionary as the second argument as defaults too.

    As such, the ** can be omitted altogether, in both 2 and 3:

    collections.defaultdict(lambda: 'blinn', {0: 'constant', 1:'lambert'})
    

    Demo in Python 2, showing you get the same output:

    >>> import sys
    >>> sys.version_info
    sys.version_info(major=2, minor=7, micro=12, releaselevel='final', serial=0)
    >>> import collections
    >>> collections.defaultdict(lambda: 'blinn', **{0: 'constant', 1:'lambert'})  == collections.defaultdict(lambda: 'blinn', {0: 'constant', 1:'lambert'})
    True
    >>> collections.defaultdict(lambda: 'blinn', **{0: 'constant', 1:'lambert'})
    defaultdict(<function <lambda> at 0x102426410>, {0: 'constant', 1: 'lambert'})
    >>> _[0]
    'constant'
    >>> collections.defaultdict(lambda: 'blinn', {0: 'constant', 1:'lambert'})
    defaultdict(<function <lambda> at 0x102426410>, {0: 'constant', 1: 'lambert'})
    >>> _[0]
    'constant'
    

    and in Python 3:

    >>> import sys
    >>> sys.version_info
    sys.version_info(major=3, minor=6, micro=0, releaselevel='beta', serial=3)
    >>> import collections
    >>> collections.defaultdict(lambda: 'blinn', {0: 'constant', 1:'lambert'})
    defaultdict(<function <lambda> at 0x10e3589d8>, {0: 'constant', 1: 'lambert'})
    >>> _[0]
    'constant'