Прямой подсчет, а не инкрементный подсчет - PullRequest
0 голосов
/ 26 сентября 2018

Это производит подсчет частоты кортежей между 3 списками, это можно сделать с помощью прямого подсчета, а не инкрементного подсчета (не +=)?

Для пояснения я бы хотел обойти необходимость увеличения значения ключа для каждой итерации, используя += и непосредственно применить счет к соответствующей паре

from collections import defaultdict
from itertools import combinations

dd = defaultdict(int)

L1 = ["cat", "toe", "man"]
L2 = ["cat", "toe", "ice"]
L3 = ["cat", "hat", "bed"]

for L in [L1, L2, L3]:
    for pair in map(frozenset, (combinations(L, 2))):
        dd[pair] += 1
defaultdict(int,
            {frozenset({'cat', 'toe'}): 2,
             frozenset({'cat', 'man'}): 1,
             frozenset({'man', 'toe'}): 1,
             frozenset({'cat', 'ice'}): 1,
             frozenset({'ice', 'toe'}): 1,
             frozenset({'cat', 'hat'}): 1,
             frozenset({'bed', 'cat'}): 1,
             frozenset({'bed', 'hat'}): 1})

1 Ответ

0 голосов
/ 26 сентября 2018

Счет не хранится в любом месте, поэтому итерация неизбежна.Но вы можете использовать collections.Counter с выражением генератора, чтобы избежать явного цикла for:

from collections import Counter
from itertools import chain, combinations

L1 = ["cat", "toe", "man"]
L2 = ["cat", "toe", "ice"]
L3 = ["cat", "hat", "bed"]

L_comb = [L1, L2, L3]

c = Counter(map(frozenset, chain.from_iterable(combinations(L, 2) for L in L_comb)))

Результат:

Counter({frozenset({'cat', 'toe'}): 2,
         frozenset({'cat', 'man'}): 1,
         frozenset({'man', 'toe'}): 1,
         frozenset({'cat', 'ice'}): 1,
         frozenset({'ice', 'toe'}): 1,
         frozenset({'cat', 'hat'}): 1,
         frozenset({'bed', 'cat'}): 1,
         frozenset({'bed', 'hat'}): 1})
...