Добавление к словарю списков с пониманием словаря

Предположим, у меня есть большой список слов. Например:

>>> with open('/usr/share/dict/words') as f:
...     words=[word for word in f.read().split('\n') if word]

Если бы я хотел построить индекс по первой букве этого списка слов, это было бы легко:

d={}
for word in words:
   if word[0].lower() in 'aeiou':
       d.setdefault(word[0].lower(),[]).append(word)
       # You could use defaultdict here too...

Результат примерно такой:

{'a':[list of 'a' words], 'e':[list of 'e' words], 'i': etc...}

Есть ли способ сделать это с пониманием dict Python 2.7, 3+? Другими словами, возможно ли с помощью синтаксиса понимания словаря добавить список, представленный ключом, по мере создания словаря?

то есть:

  index={k[0].lower():XXX for k in words if k[0].lower() in 'aeiou'}

Где XXX выполняет операцию добавления или создание списка для ключа при создании index.

Изменить

Принятие предложений и сравнительный анализ:

def f1():   
    d={}
    for word in words:
        c=word[0].lower()
        if c in 'aeiou':
           d.setdefault(c,[]).append(word)

def f2():
   d={}
   {d.setdefault(word[0].lower(),[]).append(word) for word in words 
        if word[0].lower() in 'aeiou'} 

def f3():
    d=defaultdict(list)                       
    {d[word[0].lower()].append(word) for word in words 
            if word[0].lower() in 'aeiou'}         

def f4():
    d=functools.reduce(lambda d, w: d.setdefault(w[0], []).append(w[1]) or d,
       ((w[0].lower(), w) for w in words
        if w[0].lower() in 'aeiou'), {}) 

def f5():   
    d=defaultdict(list)
    for word in words:
        c=word[0].lower() 
        if c in 'aeiou':
            d[c].append(word)       

Производит этот тест:

   rate/sec    f4     f2     f1     f3     f5
f4       11    -- -21.8% -31.1% -31.2% -41.2%
f2       14 27.8%     -- -11.9% -12.1% -24.8%
f1       16 45.1%  13.5%     --  -0.2% -14.7%
f3       16 45.4%  13.8%   0.2%     -- -14.5%
f5       18 70.0%  33.0%  17.2%  16.9%     --

Прямой цикл со словарем по умолчанию является самым быстрым, за ним следуют понимание набора и цикл с setdefault.

Спасибо за идеи!

8
задан the wolf 30 June 2012 в 20:13
поделиться