Другой подход заключается в создании словаря, использующего позиции для каждой пары подпунктов в качестве ключей.
С учетом
import more_itertools as mit
iterables = [
(("a", "apple"), ("b", "mango"), ("c", "grapes")),
(("a", "apple"), ("b", "mango"), ("c", "grapes")),
(("e", "apple"), ("b", "mango"), ("c", "grapes")),
(("a", "apple"), ("d", "mango"), ("c", "peach")),
(("e", "apple"), ("d", "mango"), ("f", "grapes")),
(("f", "grapes"), ("e", "apple"), ("d", "mango")),
(("f", "peach"), ("e", "apple"), ("e", "mango")),
(("f", "grapes"), ("c", "apple"), ("d", "mango")),
(("e", "apple"), ("f", "grapes"), ("d", "mango")),
(("a", "apple"), ("c", "grapes"), ("b", "mango")),
]
whitelisted = "apple mango".split()
Код
Сначала мы строим список индексов для locate
вхождений whitelisted
подпунктов в iterables
.
pred = lambda x: x[1] in set(whitelisted)
indices = [tuple(mit.locate(t, pred=pred)) for t in iterables]
print(indices)
# [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (1, 2), (1, 2), (1, 2), (0, 2), (0, 2)]
Наконец, map_reduce
- это один из способов сделать defaultdict
с пользовательскими ключами и значениями.
result = mit.map_reduce(zip(indices, iterable), keyfunc=lambda x: x[0], valuefunc=lambda x: x[1])
result
выход
defaultdict(None,
{(0, 1): [(('a', 'apple'), ('b', 'mango'), ('c', 'grapes')),
(('a', 'apple'), ('b', 'mango'), ('c', 'grapes')),
(('e', 'apple'), ('b', 'mango'), ('c', 'grapes')),
(('a', 'apple'), ('d', 'mango'), ('c', 'peach')),
(('e', 'apple'), ('d', 'mango'), ('f', 'grapes'))],
(1, 2): [(('f', 'grapes'), ('e', 'apple'), ('d', 'mango')),
(('f', 'peach'), ('e', 'apple'), ('e', 'mango')),
(('f', 'grapes'), ('c', 'apple'), ('d', 'mango'))],
(0, 2): [(('e', 'apple'), ('f', 'grapes'), ('d', 'mango')),
(('a', 'apple'), ('c', 'grapes'), ('b', 'mango'))]})
Детали
Для каждого кортежа в iterables
, locate
используется для получения индексов для элементов, принадлежащих к набору whitelisted
элементов. Эти результаты достаточны для группировки элементов вместе. Тем не менее, легче увидеть реальные возвращенные элементы, поэтому далее мы создаем словарь с map_reduce
.
Итерируем zip из (indices, iterables)
пар. keyfunc
преобразует indices
в качестве ключей. Аналогично, valuefunc
преобразует iterables
в значения. В результате получается defaultdict
со значениями, сгруппированными по подпозициям из whitelisted
элементов apple
и mango
.