How do I do advanced Python hash autovivification?

前端 未结 4 506
春和景丽
春和景丽 2021-01-02 04:30

This question is about implementing the full Perl autovivification in Python. I know similar questions were asked before and so far the best answer is in \"What is the best

4条回答
  •  心在旅途
    2021-01-02 05:21

    Just expanding on Ignacio's answer to present some additional options that allow you to explicitly request more magical behaviour from Python dictionaries. The maintainability of code written this way remains dubious, but I wanted to make it crystal clear that it is a question of "Is this kind of data structure maintainable?" (I have my doubts) not "Can Python be made to behave this way?" (it certainly can).

    To support arbitrary levels of nesting for the namespace aspect, all you have to do is name the function (instead of using lambda) and make it self-referential:

    >>> from collections import defaultdict
    >>> def autodict(): return defaultdict(autodict)
    ...
    >>> a = autodict()
    >>> a[1][2][3] = []
    >>> type(a[1])
    
    >>> type(a[1][2])
    
    >>> type(a[1][2][3])
    
    >>> a[1][2][3]
    []
    

    However, this introduces the "problem" that you have to set a list explicitly before you can append to it. Python's answer to that lies in the setdefault method, which has actually been around longer than collections.defaultdict:

    >>> a.setdefault(3, []).append(10)
    >>> a.setdefault(3, []).append(11)
    >>> a[3]
    [10, 11]
    >>> a[2].setdefault(3, []).append(12)
    >>> a[2].setdefault(3, []).append(13)
    >>> a[2][3]
    [12, 13]
    >>> a[1][2].setdefault(3, []).append(14)
    >>> a[1][2].setdefault(3, []).append(15)
    >>> a[1][2][3]
    [14, 15]
    

    All collections.defaultdict really does is make the common case where you always pass the same second parameter to dict.setdefault much easier to use. For more complex cases, such as this one, you can still use dict.setdefault directly for the aspects that collections.defaultdict can't handle.

提交回复
热议问题