Python - Добавление новых записей в словарь при переборе другого словаря. - PullRequest
0 голосов
/ 28 февраля 2020

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

RuntimeError: dictionary changed size during iteration


for k1 in d1:
    for k2 in d2:
        if(overlap(k1,k2)==False):
            d2[len(d2)+1]=d1[k1]                

Есть ли другой способ реализовать это?

Редактировать:

d1 = {"file1":[2,3],"file2":[11,15]}
d2 = {1:[1,5],2:[6,10]}

Вывод:

d2 = {1:[1,5],2:[6,10],3:[11,15]}

Ответы [ 4 ]

2 голосов
/ 28 февраля 2020

Я полагаю, вы ищете dict.update():

d1 = {'foo': 0,
      'bar': 1}

d2 = {'foo': 0,
      'bar': 1,
      'baz': 2}

d1.update(d2)

В результате:

d1 = {'foo': 0,
      'bar': 1,
      'baz': 2}

Редактировать:

import itertools

d1 = {"file1":[2,3],
      "file2":[11,15]}

d2 = {1:[1,5],
      2:[6,10]}

d2 = {**d2, **{max(d2.keys())+i+1: v for i, (k, v) in enumerate({k: v for k, v in d1.items() if not any(i in range(v[0], v[1]+1) for i in itertools.chain.from_iterable(range(v[0], v[1]+1) for v in d2.values()))}.items())}}

Производит:

d2 = {1: [1, 5],
      2: [6, 10],
      3: [11, 15]}

?

1 голос
/ 28 февраля 2020

Если вы пытаетесь объединить словари, то более быстрый способ - использовать один из этих

a = dict(one=1,two=2,three=3,four=4,five=5,six=6)
b = dict(one=1,two=2,three=5,six=6, seven=7, nine=9)
a.update(b)

, который дает {'one': 1, 'two': 2, 'three': 5, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'nine': 9}

Или вы можете использовать c = dict(a, **b)

0 голосов
/ 29 февраля 2020

Судя по вашему описанию, редактированию и комментариям, оно не похоже на dict.update(), которое даст вам желаемые результаты.

Ошибка, которую вы нажимаете, заключается в том, что l oop создает предположение о количестве элементов, которые будут повторяться после запуска. В течение l oop вы меняете это число, отменяя предположение и вызывая сбой программы.

Чтобы исправить это, вам нужно вместо этого выполнить итерацию копии элементов. Вы также упомянули, что вас интересуют значения, а не ключи, поэтому вам нужно настроить что вы итерируете.

Теперь вы на самом деле не публиковали то, что overlap функция делает, поэтому я предполагаю что-то подобное на основе ваших комментариев / образца:

def overlap(left, right):
    return left[0] - right[-1] == 1

По большей части, фактическая реализация вашего overlap не имеет отношения к вопросу, но приведенный выше код, по крайней мере, дал мне ожидаемый результат.

Затем я настроил ваш код следующим образом:

for v1 in list(d1.values()):
    for v2 in list(d2.values()):
        # If v1 overlaps v2
        if overlap(v1, v2):
            # Add v1 to d2 under the next sequential key
            d2[len(d1) + 1] = v1

Используя list(d1.values()), я больше не выполняю итерации сам словарь при его изменении - я делаю «снимок» содержимого (значения здесь указаны) в начале l oop.

Используя это и ваши примеры данных, d2 содержит {1: [1, 5], 2: [6, 10], 3: [11, 15]} после l oop.

0 голосов
/ 28 февраля 2020

Вам не нужен двойной l oop там. L oop через ключи в d1. Проверьте, содержит ли d2.keys k1. Если нет, добавьте k1 к d2. У меня нет синтаксиса здесь, но что-то вроде этого.

for k1 in d1.keys:
    if not k1 in d2.keys:
        d2[k1] = d1[k1]

return d2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...