Заменить список значений словаря

#python #python-3.x #dictionary

#python #python-3.x #словарь

Вопрос:

Учитывая словарь со списком list в качестве значений, как заменить некоторые из подсписков в списке значений с учетом конкретных критериев.

Пока что я пробовал перебирать все подсписки по длине и оценивать общее значение в обоих подсписках.

Например, учитывая следующий словарь:

 d = {(1, 2): [[0, 14], [3]], (10, 12): [[9, 11], [13]]}
  

и подсписок для сравнения с:

 candidates = [14,9]
  

Я ожидал бы, что мой вывод будет :

 d = {(1, 2): [14, 3], (10, 12): [9, 13]}
  

Что я пробовал до сих пор, так это перебирать все подсписки по длине и заменять для пересечения обоих подсписков:

 for k,v in d.items():
    for l in v():
        if len(l) > 1:
            v = list(set(l).intersection(candidates)))
  

Выходные данные представляют общие элементы между списком кандидатов и теми подсписками, длина которых > 1. В результате подсписок [0,14] был бы заменен на [14] , который является общим элементом. Этот подсписок [4] может быть в конечном итоге объединен со [3] списком по тому же ключу. В результате [14,3] . Та же логика справедлива для второго ключа и списка подсписков

Но я немного застрял в обновлении dict, сохраняя и в конечном итоге объединяя эти подсписки, длина которых < 1.

Есть какой-нибудь намек?

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

1. Можете ли вы подробнее рассказать о том, что представляет собой ожидаемый результат?

2. Я не могу это получить. если входной список списков равен [[0, 14], [3]], каким должно быть ожидаемое пересечение с [14,9] [14,3]? Можете ли вы пояснить, каким именно должен быть результат, которого вы ожидаете?

3. Выходные данные представляют общие элементы между списком кандидатов и теми подсписками, длина которых > 1. В результате подсписок [0,14] был бы заменен на [14] , который является общим элементом. Этот подсписок [4] может быть в конечном итоге объединен со [3] списком по тому же ключу. В результате [14,3] . Та же логика справедлива для второго ключа и списка подсписков

Ответ №1:

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

ДЕМОНСТРАЦИЯ:

 l = [1,2,3]
for i in l:
    i = 0        # only changes i, no effect on l

l = [1,2,3]
for i, j in enumerate(l):
    l[j] = 0     # actually changes l
  

Что касается части слияния, я просто предположу, что вы объединяетесь, если все списки под ключом имеют длину <= 1:

 for k,v in d.items():
    merge = True
    for i,l in enumerate(v):
        if len(l) > 1:
            v[i] = list(set(l).intersection(candidates))
        if len(v[i]) > 1:
            merge = False
    if merge:
        d[k] = [l[0] for l in v]
  

Ответ №2:

Вы можете использовать понимание dict, которое выполняет итерацию по элементам dict, и использовать понимание вложенного списка для итерации по вложенным спискам, и для каждого вложенного списка в вложенном списке длиной больше 1 используйте set intersection с кандидатами:

 {k: [i for s in l for i in (set(s).intersection(candidates) if len(s) > 1 else s)] for k, l in d.items()}
  

Это возвращает:

 {(1, 2): [14, 3], (10, 12): [9, 13]}