Conjoin function made in functional style

后端 未结 2 381
情深已故
情深已故 2021-01-13 01:46

Recently, reading Python \"Functional Programming HOWTO\", I came across a mentioned there test_generators.py standard module, where I found the following gener

2条回答
  •  伪装坚强ぢ
    2021-01-13 02:36

    This seems to work, and it's still lazy:

    def conjoin(gs):
        return [()] if not gs else (
            (val,) + suffix for val in gs[0]() for suffix in conjoin(gs[1:])
        )
    
    def range3():
        return range(3)
    
    print list(conjoin([range3, range3]))
    

    Output:

    [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
    

    Example usage to show mutable state:

    x = ""
    def mutablerange():
        global x
        x += "x"
        return [x + str(i) for i in range(3)]
    
    print list(conjoin([range3, mutablerange]))
    

    Output: (watch the increasing number of 'x's)

    [(0, 'x0'), (0, 'x1'), (0, 'x2'), (1, 'xx0'), (1, 'xx1'), (1, 'xx2'), (2, 'xxx0'), (2, 'xxx1'), (2, 'xxx2')]
    

    And if we use itertools.product:

    x = ""
    print list(itertools.product(range3(), mutablerange()))
    

    the result is the following:

    [(0, 'x0'), (0, 'x1'), (0, 'x2'), (1, 'x0'), (1, 'x1'), (1, 'x2'), (2, 'x0'), (2, 'x1'), (2, 'x2')]
    

    So, one clearly see, that itertools.product caches the values returned by the iterator.

提交回复
热议问题