Словарь, возвращающий только последний элемент в значении списка

#python #list #if-statement #string-formatting #dictionary-comprehension

#python #Список #if-оператор #форматирование строки #словарь-понимание

Вопрос:

У меня есть 2 списка в качестве входных данных:

 A = ['A', 'B', 'C', 'D', 'E']
sessionid = [1, 1, 3, 2, 2]
  

Я хочу использовать понимание словаря без импорта каких-либо библиотек для генерации следующего вывода с ключом как ‘Session x’, используя форматирование строки:

 {'Session 1': ['A','B'], 'Session 2': ['D','E'], 'Session 3': ['C']}
  

Я пробовал с этим кодом:

 dictb = {'Session {}'.format(session): [a if session not in dictb.keys() else [a]] for a,session in list(zip(A,sessionid))}
  

но он возвращает мне это:

 {'Session 1': ['B'], 'Session 3': ['C'], 'Session 2': ['E']}
  

Я думаю, что есть проблема с if-else statement пониманием. Как мне следует это улучшить?

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

1. Вы хотите лучший способ, что-то короткое и pythonic?

2. Я слышал, что defaultdict это может делать подобные вещи

3. Да, но поскольку вы не хотите ничего импортировать, мы можем обойтись без этого.

Ответ №1:

Вот возможное решение:

 dictb = {f'Session {k}': [v for v, i in zip(A, sessionid) if k == i]
         for k in sorted(set(sessionid))}
  

Вывод:

 {'Session 1': ['A', 'B'], 'Session 2': ['D', 'E'], 'Session 3': ['C']}
  

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

1. В чем разница между sorted(sessionid) и sorted(set(sessionid)) ?

2. @cwyjm когда вы применяетесь set к списку, он сохраняет элементы без двойников. Таким образом, в этом случае возвращается первый фрагмент кода [1,1,2,2,3] , второй возвращает [1,2,3]

3. Таким set образом, возвращаются только отдельные значения в списке. Большое вам спасибо!

Ответ №2:

Это связано с тем, что вы создаете словарь со строковыми ключами, которые имеют формат Session{} , и проверяете, есть ли в словаре целочисленные ключи, которых у него всегда нет, и, таким образом, он принимает часть после else . Когда приходит одно и то же целое число, оно обновляет значение, и именно поэтому вы видите последнее обновленное значение. Я бы не рекомендовал делать то, что вы хотите, используя понимание dict, как по соображениям производительности, так и по удобочитаемости, но если вы действительно хотите, попробуйте (не проверено):

 dictb = {'Session {}'.format(session): [dictb['Session {}'.format(session)]   [a] if 'Session {}'.format(session) not in dictb.keys() else [a]] for a,session in list(zip(A,sessionid))}
  

Рекомендуемый подход будет:

 dictb = {}
for a, session in zip(A, sessionid):
    key = 'Session {}'.format(session)
    if key in dictb:
        dictb[key].append(a)
    else:
        dictb[key] = [a]
  

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

1. Я всегда затрудняюсь с пониманием словаря из-за его удобочитаемости. Это правда, что вашему подходу легче следовать. Логика понятнее при использовании цикла for . Но я должен использовать понимание в этой задаче так.. В любом случае спасибо за ваши ответы! 🙂