#python
#python
Вопрос:
У меня есть следующий список в python:
rooms = [1,'John','Mike','Simona',2,'Peter','Mark',3,'Olivia']
И я хотел бы преобразовать его в словарь. Целые числа указывают номера, а имена являются строками:
rooms = {'room1': ['John','Mike','Simona'], 'room2': ['Peter','Mark'], 'room3': ['Olivia']}
Как я могу сделать это элегантным способом?
Комментарии:
1. Что, если первый элемент не является целым числом?
2. Хороший вопрос. Это было бы исключением, но мы можем оставить это необработанным
Ответ №1:
Вы можете группировать по типу, используя itertools.groupby()
:
from itertools import groupby
grouped = groupby(rooms, type)
rooms = {}
for key, grp in grouped:
roomname = 'room{}'.format(next(grp))
rooms[roomname] = list(next(grouped)[1])
Это разделяет ваш список ввода на группы по типу объекта. Это дает вам чередующиеся группы значений int
и str
. Затем цикл извлекает нечетные группы (целые числа); next(grouped)
вызов в теле цикла извлекает четные группы.
Это предполагает, что а) ваше первое значение — это номер комнаты, и б) за номером комнаты никогда не следует другое целое число. Если это так, эти целые числа вообще игнорируются.
ДЕМОНСТРАЦИЯ:
>>> from itertools import groupby
>>> rooms = [1,'John','Mike','Simona',2,'Peter','Mark',3,'Olivia']
>>> grouped = groupby(rooms, type)
>>> rooms = {}
>>> for key, grp in grouped:
... roomname = 'room{}'.format(next(grp))
... rooms[roomname] = list(next(grouped)[1])
...
>>> rooms
{'room2': ['Peter', 'Mark'], 'room3': ['Olivia'], 'room1': ['John', 'Mike', 'Simona']}
Комментарии:
1. Разумное использование
type
там 🙂2. Примечание: если сортировка важна, используйте
oredereddict
Ответ №2:
Вам поможет следующее.
rooms = [1,'John','Mike','Simona',2,'Peter','Mark',3,'Olivia']
new_dict = {}
for value in rooms:
if isinstance(value, int):
ID = "room" str(value)
else:
new_dict.setdefault(ID, []).append(value)
print new_dict
ВЫВОД:
{'room1': ['John', 'Mike', 'Simona'], 'room2': ['Peter', 'Mark'], 'room3': ['Olivia']}
Комментарии:
1. Зачем
while
цикл с увеличениемindex
, когда вы могли бы просто использоватьfor
цикл здесь?2. Нет, просто перебирайте
rooms
напрямую;range()
здесь это не нужно.for value in rooms:
. Обратите внимание, что для проверки целых чисел вам действительно следует использоватьisinstance()
here .if isinstance(value, int):
.3. Отредактировано снова… Многому учусь у вас. 🙂