Можно закодировать более общее решение этой проблемы. Следующее работает в Python 3.0, независимо от уровня вложенности .
Давайте определим recursive_map
:
import collections
def recursive_map(f, iterable):
for e in iterable:
if isinstance(e, collections.Iterable):
yield recursive_map(f, e)
else:
yield f(e)
Теперь запрошенная функция отрицания может быть закодирована следующим образом:
import functools
import operator
negate = functools.partial(recursive_map, operator.neg)
Таким образом, для некоторого набора произвольно вложенных итераций x
мы вычисляем его отрицание y
следующим образом:
y = negate(x)
Добавление:
Как отметил пользователь chradcliffe , вышеуказанная функция negate
дает генератор, который может содержать другие генераторы, которые ... и т. Д. Чтобы расширить / оценить все эти генераторы, нам нужно применить list()
всем им. Итак, мы определили еще одну общую функцию отображения, на этот раз ту, которая работает над самими итерациями.
def recursive_iter_map(f, iterable):
def rec(e):
if isinstance(e, collections.Iterable):
return recursive_iter_map(f, e)
else:
return e
return f(map(rec, iterable))
Теперь
all_lists = functools.partial(recursive_iter_map, list)
y = all_lists(negate(x))
фактически сразу отрицает каждый элемент и возвращает полный список.
Обратите внимание, что мы можем рассматривать вложенную коллекцию итераций как дерево . Каждое итерируемое - это поддерево, а не итерируемое - это листья. Следовательно, первая определенная мной функция работает с листьями, а вторая - с не листьями.