Python: Map a function over recursive iterables

后端 未结 5 2309
孤独总比滥情好
孤独总比滥情好 2021-02-13 11:42

I have an arbitrarily nested iterable like so:

numbers = (1, 2, (3, (4, 5)), 7)

and I\'d like to map a function over it without changing the st

5条回答
  •  名媛妹妹
    2021-02-13 12:17

    I extended the notion of a recursive map to work on the standard python collections: list, dict, set, tuple:

    def recursiveMap(something, func):
      if isinstance(something, dict):
        accumulator = {}
        for key, value in something.items():
          accumulator[key] = recursiveMap(value, func)
        return accumulator
      elif isinstance(something, (list, tuple, set)):
        accumulator = []
        for item in something:
          accumulator.append(recursiveMap(item, func))
        return type(something)(accumulator)
      else:
        return func(something)
    

    This passes the following tests, which I'll include mostly as examples of usage:

    from hypothesis                 import given
    from hypothesis.strategies      import dictionaries, text
    from server.utils               import recursiveMap
    
    
    def test_recursiveMap_example_str():
      assert recursiveMap({'a': 1}, str) == {'a': '1'}
      assert recursiveMap({1: 1}, str) == {1: '1'}
      assert recursiveMap({'a': {'a1': 12}, 'b': 2}, str) == {'a': {'a1': '12'}, 'b': '2'}
      assert recursiveMap([1, 2, [31, 32], 4], str) == ['1', '2', ['31', '32'], '4']
      assert recursiveMap((1, 2, (31, 32), 4), str) ==  ('1', '2', ('31', '32'), '4')
      assert recursiveMap([1, 2, (31, 32), 4], str) ==  ['1', '2', ('31', '32'), '4']
    
    
    @given(dictionaries(text(), text()))
    def test_recursiveMap_noop(dictionary):
      assert recursiveMap(dictionary, lambda x: x) == dictionary
    

提交回复
热议问题