Лучший способ идентифицировать дубликаты в двух списках или словаре? - PullRequest
0 голосов
/ 08 ноября 2019

Допустим, у вас есть два списка, таких как:

list1 = [-2, -1, 0, 1, 2, 3]
list2 = [4, 1, 0, 1, 4, 9]

... и два списка были упакованы в словарь для получения:

dict1 = {-2: 4, 
         -1: 1, 
          0: 0, 
          1: 1, 
          2: 4, 
          3: 9}

... где list1это ключ, а список 2. это значение.

Вы заметите, что некоторые элементы в списке 2 являются дубликатами, такими как 4 и 1. Они отображаются дважды в списке 2 и, следовательно, в словаре.

-2 corresponds to 4
 2 corresponds to 4
-1 corresponds to 1
 1 corresponds to 1

Я пытаюсь найти способ либо использовать списки, либо словарь , чтобы идентифицировать дубликаты элементов в списке 2 и вернуть их ключи из списка 1.

Таким образом, возвращаемые значения, которые я ожидаю из двух списков выше, будут:

(-2, 2) #From list 1 since they both correspond to 4 in list2
(-1, 1) #from list 1 since they both correspond to 1 in list2

В этом примере list2 оказывается квадратом list1. Но это не всегда так.

Итак, в конечном итоге, я ищу способ вернуть эти ключи на основе их дублированных значений.

Есть мысли о том, как к этому подойти? Я могу идентифицировать дубликаты в списке 2, но я полностью застрял в том, как определить их соответствующие значения в списке 1.

1 Ответ

0 голосов
/ 10 ноября 2019

В python3:

from itertools import groupby
list1 = [-2, -1, 0, 1, 2, 3]
list2 = [4, 1, 0, 1, 4, 9]
pairs = zip(list2, list1)
ordered = sorted(pairs, key=lambda x: x[0])
groups = ((k, list(g)) for k,g in groupby(ordered, key=lambda x: x[0])) # generator
duplicates = (k for k in groups if len(k[1])>1) # generator
for k,v in duplicates :
    print(str(k) + " : " + str(list(v)))

результат:

1 : [(1, -1), (1, 1)]
4 : [(4, -2), (4, 2)]

Бонус: в функционале c #:

var list1 = new[] { -2, -1, 0, 1, 2, 3 };
var list2 = new[] { 4, 1, 0, 1, 4, 9 };
var g = list1.Zip(list2, (a, b) => (a, b)) //create tuples
    .GroupBy(o => o.b, o => o.a, (k, group) => new { key = k, group = group.ToList() }) //create groups
    .Where(o => o.group.Count > 1) // select group with minimum 2 elements
    .ToList(); // no lazy
foreach (var kvp in g)
    Console.WriteLine($"{kvp.key}: {string.Join(",", kvp.group)}");

результат:

4: -2,2
1: -1,1
...