Как получить словарь со значениями, которые являются списком, содержащим индексы каждого ключа
Мой код:
def collect_ind(source):
keys = []
indexes = []
for x in source:
keys.append(x)
i = 0
while i < len(source):
indexes.append([i])
i += 1
print(keys, '=', indexes)
# return keys, indexes
dictionary = dict(zip(keys, indexes))
print(dictionary)
return dictionary # {'g': [0], 'o': [2]}
collect_ind('goo')
Как сделать так, чтобы функция возвращала словарь, в котором будут индексы каждого встретившегося ключа? Сейчас моя функция возвращает {'g': [0], 'o': [2]}, а должно быть: {'g': [0], 'o': [1, 2]}, ведь 'o' - встречается 2 раза в списке. Помогите пожалуйста! Я новичок в Python.
Ответы (3 шт):
Вот так:
def collect_ind(src):
dictionary = dict()
for i in range(len(src)):
key = src[i]
try:
dictionary[key].append(i)
except KeyError:
dictionary[key] = [i]
return dictionary
collect_ind('goo')
Можно сделать вспомогательную функцию (однако этот вариант сильно дольше):
def find_all(src, el):
return [i for i in range(len(src)) if src[i] == el]
def collect_ind(src):
dictionary = {key: find_all(src, key) for key in src}
return dictionary
Второй вариант, но find_all быстрее:
def find_all(src, el):
result = []
offset = -1
while True:
try:
offset = src.index(el, offset+1)
except ValueError:
return result
result.append(offset)
def collect_ind(src):
dictionary = {key: find_all(src, key) for key in src}
return dictionary
Довольно же просто решается прямо "в лоб" с использованием enumerate (с помощью него можно получить пары индекс-значение для коллекции) и метода .get для словаря (позволяющего задать дефолтное значение для ключей, которых нет в словаре):
def collect_ind(src):
d = {}
for i,x in enumerate(src):
d[x] = d.get(x, []) + [i]
return d
print(collect_ind('goo'))
Вывод:
{'g': [0], 'o': [1, 2]}
а если списки заменить на таплы, то получится как-то так:
def collect_ind(source):
d = dict.fromkeys(source,())
for i,x in enumerate(source):
d[x] += (i,)
return d
collect_ind('google')
# {'g': (0, 3), 'o': (1, 2), 'l': (4,), 'e': (5,)}