#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 . Но я должен использовать понимание в этой задаче так.. В любом случае спасибо за ваши ответы! 🙂