Home > Uncategorized > The final literals vs constructors argument

The final literals vs constructors argument

February 4, 2010
>>> def literal():
...     a = {}
...     b = []
... 
>>> def builtinconstructor():
...     a = dict()
...     b = list()
... 
>>> import dis
>>> dis.dis(literal)
  3           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  4           6 BUILD_LIST               0
              9 STORE_FAST               1 (b)
             12 LOAD_CONST               0 (None)
             15 RETURN_VALUE        
>>> dis.dis(builtinconstructor)
  3           0 LOAD_GLOBAL              0 (dict)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (a)

  4           9 LOAD_GLOBAL              1 (list)
             12 CALL_FUNCTION            0
             15 STORE_FAST               1 (b)
             18 LOAD_CONST               0 (None)
             21 RETURN_VALUE        
>>> 

Seriously now, is there any reason to use constructors instead of literals for empty dicts/lists ?

About these ads
Tags:
  1. Doug Napoleone
    February 5, 2010 at 3:12 am

    The only case I can think of is due to closures.

    multidict.setdefault(key, dict())[otherkey] = value

    hashtable.setdefault(hashofvalue, list()).append(value)

    Ok, not the BEST examples, and I hate it when I see people do this to cram more stuff onto one line… but this is because we want a new construction on each iteration (very wasteful, but safe).

  2. Jean-Paul Calderone
    February 5, 2010 at 4:07 am

    You can pass the type objects (“constructors”) around, since they’re actual objects. This is sometimes useful. For example:

    import collections
    x = collections.defaultdict(list)
    print x['foo']

    Compare this to the version using the literal syntax:

    x = collections.defaultdict(lambda: list)

    I think the former is clearly better.

    Also, I don’t think I understand your argument. Surely the bytecode that the two variations compile to is very near the *bottom* of the list of things to consider when trying to select a construct to use. Readability, testability – let’s just say maintainability – for example, should count much higher.

    In general, I agree that [] should be preferred over list(), though, but I don’t think that’s always the case, and I don’t think the presence of a special op code in CPython is a compelling argument for that conclusion.

  3. February 5, 2010 at 7:42 am

    Readability? At least dict and list are consistent with set, frozenset et al.

  4. xtian
    February 5, 2010 at 10:34 am

    @Doug – even if you used the literal forms in setdefault calls, the lists are all created separately each time it’s called:

    >>> d = {}
    >>> for i in range(10):
    … d.setdefault(i, []).append(i)

    >>> d
    {0: [0], 1: [1], 2: [2], 3: [3], 4: [4], 5: [5], 6: [6], 7: [7], 8: [8], 9: [9]}

    If the default list was only created once the dictionary values would all be the same.

  5. February 6, 2010 at 12:32 am

    This is a bit dated (2006?), but constructors are more enterprisey ;-)

  6. Ben Finney
    February 7, 2010 at 2:30 am

    Seriously now, is minimisation of bytecode instructions the only consideration when writing Python code?

  1. No trackbacks yet.
Comments are closed.
Follow

Get every new post delivered to your Inbox.

Join 172 other followers