#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]}