Python - Как рассчитать равные части двух словарей? - PullRequest
4 голосов
/ 12 марта 2009

У меня проблема с объединением или вычислением общей / равной части этих двух словарей. В моих словарях значения являются списками:

d1 = {0:['11','18','25','38'], 
      1:['11','18','25','38'], 
      2:['11','18','25','38'], 
      3:['11','18','25','38']}

d2 = {0:['05','08','11','13','16','25','34','38','40', '43'], 
      1:['05', '08', '09','13','15','20','32','36','38', '40','41'], 
      2:['02', '08', '11', '13', '18', '20', '22','33','36','39'], 
      3:['06', '11', '12', '25', '26', '27', '28', '30', '31', '37']}

Я бы хотел проверить "d2" и узнать, есть ли числа из "d1". Если они есть, я бы хотел обновить один из них новыми данными или получить в 3-м словаре «d3» только те значения, которые идентичны / равны как в «d1», так и в «d2», например:

d3 = {0:['11','25','38'], 1:['38'], 2:['11','18'], 3:['11','25']} 

Может ли кто-нибудь помочь мне с этим?

Моя вина, что я забыл быть более конкретным. Я ищу решение на Python.

Ответы [ 5 ]

7 голосов
/ 12 марта 2009

Предполагая, что это Python, вы хотите:

dict((x, set(y) & set(d1.get(x, ()))) for (x, y) in d2.iteritems())

для генерации результирующего словаря "d3".

Python 3.0+ версия

>>> d3 = {k: list(set(d1.get(k,[])).intersection(v)) for k, v in d2.items()}
{0: ['11', '25', '38'], 1: ['38'], 2: ['11', '18'], 3: ['11', '25']}

Вышеприведенная версия (а также версия Python 2.x) допускает пустые пересечения, поэтому в общем случае требуется дополнительная фильтрация:

>>> d3 = {k: v for k, v in d3.items() if v}

Объединение вышеперечисленного за один проход:

d3 = {}
for k, v in d2.items():
    # find common elements for d1 & d2
    v3 = set(d1.get(k,[])).intersection(v)
    if v3: # whether there are common elements
       d3[k] = list(v3) 

[Редактировать: Я сделал эту публикацию вики-сообщества, чтобы люди могли улучшить ее, если пожелают. Я допускаю, что это может быть немного трудно читать, если вы не привыкли читать подобные вещи в Python.]

4 голосов
/ 13 марта 2009

Предлагая более удобочитаемое решение:

d3= {}
for common_key in set(d1) & set(d2):
    common_values= set(d1[common_key]) & set(d2[common_key])
    d3[common_key]= list(common_values)

РЕДАКТИРОВАТЬ после предложения:

Если вам нужны только ключи, имеющие хотя бы один элемент общего значения:

d3= {}
for common_key in set(d1) & set(d2):
    common_values= set(d1[common_key]) & set(d2[common_key])
    if common_values:
        d3[common_key]= list(common_values)

Вы можете хранить значения d1 и d2 как наборы вместо списков, если порядок и дубликаты не важны.

1 голос
/ 12 марта 2009

Если мы можем предположить, что d1 и d2 имеют одинаковые ключи:

d3 = {}
for k in d1.keys():
    intersection = set(d1[k]) & set(d2[k])
    d3[k] = [x for x in intersection]

В противном случае, если мы не можем предположить, что это немного более грязно:

d3 = {}
for k in set(d1.keys() + d2.keys()):
    intersection = set(d1.get(k, [])) & set(d2.get(k, []))
    d3[k] = [x for x in intersection]

Редактировать: Новая версия с учетом комментариев. Этот проверяет только те ключи, которые имеют общие черты d1 и d2, о чем, по-видимому, спрашивает автор.

d3 = {}
for k in set(d1.keys()) & set(d2.keys()):
    intersection = set(d1[k]) & set(d2[k])
    d3[k] = list(intersection)
1 голос
/ 12 марта 2009

Проблема сводится к определению общих элементов между двумя записями. (Чтобы получить результат для всех записей, просто заключите код в цикл над всеми ними.) Кроме того, похоже, что каждая запись является набором (то есть она не имеет дублирующих элементов). Поэтому все, что вам нужно сделать, это найти пересечение множества между этими элементами. Многие языки предлагают метод или функцию для этого; например, в C ++ используйте контейнер set и функцию set_intersection. Это намного эффективнее, чем сравнивать каждый элемент в одном наборе с другим, как предлагали другие.

0 голосов
/ 12 марта 2009

в псевдокоде:

Dictionary d3 = new Dictionary()
for (i = 0 to min(d1.size(), d2.size()))
{
  element shared = getSharedElements(d1[i], d2[i]);
  d3.store(i, shared);
}

function getsharedElements(array e1, array e2)
{
  element e3 = new element();
  for (int i = 0 to e1.length)
  {
    if (e2.contains(e1[i]))
    {
      e3.add[e1[i]];
    }
  }
  return e3;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...