Как я могу подсчитать количество вхождений нескольких пересечений во вложенном списке

#python #set #itertools #nested-lists

#python #установить #python-itertools #вложенные списки

Вопрос:

ОБНОВЛЕННЫЙ ВОПРОС: у меня есть несколько вложенных списков, похожих на этот:

 l = [['y', 'ha', 'ua', 'uk'], ['o', 'j', 'sb', 'ku'], 
['j', 'c', 'ts', 'ar'], ['nec', 'hv', 'f', 'uf'], 
['y', 'nec', 'fs', 'ks']]
  

Каждый список представляет собой группу людей, а каждый подсписок — характеристики одного человека. Я хочу подсчитать количество людей с перекрывающимися характеристиками.

Я создал словарь счетчиков, чтобы найти все результаты> 1.

 dups = dict((k, v) for k, v in dups.items() if (v >= 2))
#{'y': 2, 'j': 2, 'nec': 2}
  

Если я добавлю значения dup вместе, я получу 6, когда есть только 5 подсписков. Мне нужно найти все подсписки с более чем одним перекрывающимся значением.

Другими словами, мой вопрос в том, как я могу получить 5 (поскольку все 5 подсписков имеют как минимум 1 общее значение).

Я попытался создать комбинации следующим образом:

 import itertools    
characteristics = list(dups.keys())
set_c = set(characteristics)
combos = list(itertools.combinations(set_c, 2))
sub_list = list(combos)
sub_list2 = [list(x) for x in sub_list]
print(sub_list2)
#[['nec', 'y'], ['nec', 'j'], ['y', 'j']]
  

Я попробовал приведенный ниже код, но у него есть проблемы (например, он не учитывает несколько логических значений):

 counter = 0
if (all(x for y in l for x in sub_list2)):
    counter  = 1
    print(counter)
else:
    print("No, list is not subset of other.")
  

Есть мысли?

Комментарии:

1. Что конкретно вы ищете? Если у вас есть два списка со значением a и еще два списка со значением b , является ли ответ 2 или 4?

2. 4. Результат в конечном итоге делится на общее число в еще большем количестве списков, чтобы вычислить% перекрытий. Данные поступают из (частей) файла csv. Это помогает?

Ответ №1:

Я не совсем понимаю требования, но это может быть то, что вы ищете:

 l = [['y', 'ha', 'ua', 'uk'], 
     ['o', 'j', 'sb', 'ku'], 
     ['j', 'c', 'ts', 'ar'], 
     ['nec', 'hv', 'f', 'uf'], 
     ['y', 'nec', 'fs', 'ks']]
     
# get all keys 
all = set()

for l2 in l:
   all |= set(l2)  # merge elements, remove duplicates

d = {k:0 for k in all}  # dictionary for counts
for l1 in l:
   for e in l1:
       d[e]  = 1

t = [(k,d[k]) for k in d if d[k] > 1] # remove count = 1

print(t)
  

Вывод

 [('j', 2), ('nec', 2), ('y', 2)]
  

Комментарии:

1. К сожалению, это не то, что я ищу. Вот другой подход к моему вопросу.