Создание словаря из списка смешанных типов

#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. Отредактировано снова… Многому учусь у вас. 🙂