2016-08-04 3 views
1

Понятно, что это довольно просто, но я не могу понять, как это понять.Использование Python dict для индексации списка слов по первой букве

Я хочу превратить список строк в dict с каждой клавишей, являющейся первой буквой списка связанных с ней слов.

# My list of sounds 
sounds = ['sniff', 'bark', 'bork', 'blork', 'heck', 'borf', 'bjork', 'boo', 'bre', 'bore'] 

# My dict comprehension which isn't working 
indexed = {s[0]: [s] for s in sounds} 

Мой выход выглядеть следующим образом:

{'h': ['heck'], 's': ['sniff'], 'b': ['bore']} 

я пропускаю функцию на добавление здесь, но каждый раз, когда я пытаюсь реализовать это не дает мне правильный выход, или он бросает SyntaxError , Что мне не хватает?

+0

2 разных значения не могут иметь один и тот же ключ. Поэтому вы просто продолжаете писать предыдущее значение каждый раз, когда появляются новые «b ...» или «h ...» или «s ...», поскольку они дают одинаковые клавиши «b», «h» и «h», s». Вероятно, вы должны прочитать о dicts ... – Julien

+2

Не используйте понимание для этого материала –

+2

Такая задача группировки не подходит для понимания. Нормальная петля работает намного лучше. – user2357112

ответ

4

это может быть сделано за один раз только с стандартной библиотекой

>>> sounds = ['sniff', 'bark', 'bork', 'blork', 'heck', 'borf', 'bjork', 'boo', 'bre', 'bore'] 
>>> result=dict() 
>>> for s in sounds: 
     result.setdefault(s[0],[]).append(s) 

>>> result 
{'b': ['bark', 'bork', 'blork', 'borf', 'bjork', 'boo', 'bre', 'bore'], 's': ['sniff'], 'h': ['heck']} 
>>> 

решения с itertools это хорошо, но это требует дополнительного шага сортировки списка, что делает его O (N журнала п), в то время как это сделать то же самое только один идти так O (п)

collections модуль предлагает defaultdict, которые имеют строение в setdeafult

>>> from collections import defaultdict 
>>> result=defaultdict(list) 
>>> for s in sounds: 
     result[s[0]].append(s) 

>>> result 
defaultdict(<class 'list'>, {'b': ['bark', 'bork', 'blork', 'borf', 'bjork', 'boo', 'bre', 'bore'], 's': ['sniff'], 'h': ['heck']}) 
>>> 
0

Это то, чего вы пытаетесь достичь?

firsts = {s[0] for s in sounds} 
indexed = {first: [s for s in sounds if s[0]==first] for first in firsts} 
+0

Это то, как заставить его работать с пониманием, но, к сожалению, он все еще O (n^2) в худшем случае всего, у кого есть собственный ключ. –

3

Нет проблем, itertools to the rescue. Вы можете сгруппировать элементы по их первой букве, а затем создать из них dict.

sounds = ['sniff', 'bark', 'bork', 'blork', 'heck', 'borf', 'bjork', 'boo', 'bre', 'bore'] 
import itertools 

grouped = itertools.groupby(sorted(sounds), key=lambda x: x[0]) 
d = {k: list(v) for k,v in grouped} 
print(d) 
+0

Красивая! Я выберу это отдельно; Спасибо за помощь! – Drew

+0

@Drew У вас есть более глубокий взгляд на itertools, он может творить чудеса (и он работает на итераторах, поэтому в некоторых случаях вы можете покрыть бесконечные последовательности и прочее). – Carsten

0

Это не очень удобно использовать для понимания dict - в итоге вы получите больше циклов, чем вам нужно. Если вы пишете его напрямую, вы только просматриваете список ввода один раз:

dict1 = {} 
for s in ['sniff', 'bark', 'bork', 'blork', 'heck', 'borf', 'bjork', 'boo', 'bre', 'bore']: 
    if not s[0] in dict1.keys(): 
    dict1[ s[0] ] = [] 
    dict1[ s[0] ].append(s)  
print dict1 
Смежные вопросы