本文介绍了通过dict理解追加到列表的dict的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有很多单词.例如:

Suppose I have a large list of words. For an example:

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

如果我想通过该单词列表的第一个字母建立索引,这很容易:

If I wanted to build an index by first letter of this word list, this is easy:

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...}

是否可以使用Python 2.7、3+ dict理解做到这一点?换句话说,使用dict理解语法是否可以在构建dict时追加由键表示的列表?

Is there a way to do this with Python 2.7, 3+ dict comprehension? In other words, is it possible with the dict comprehension syntax to append the list represented by the key as the dict is being built?

即:

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

在创建index时XXX在其中执行添加操作或为密钥创建列表的位置.

Where XXX performs an append operation or list creation for the key as index is being created.

修改

接受建议和基准测试

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%     --

具有默认dict的直接循环最快,其次是设置理解和setdefault循环.

The straight loop with a default dict is fastest followed by set comprehension and loop with setdefault.

谢谢你的想法!

推荐答案

对dict的理解是不可能的(至少容易或直接地).

It is not possible (at least easily or directly) with a dict comprehension.

使用集合或列表理解可能但可能会滥用语法:

It is possible, but potentially abusive of the syntax, with a set or list comprehension:

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

# a side effect set comprehension:  
index={}   
r={index.setdefault(word[0].lower(),[]).append(word) for word in words 
        if word[0].lower() in 'aeiou'}     

print r
print [(k, len(d[k])) for k in sorted(d.keys())]  
print [(k, len(index[k])) for k in sorted(index.keys())]

打印:

set([None])
[('a', 17094), ('e', 8734), ('i', 8797), ('o', 7847), ('u', 16385)]
[('a', 17094), ('e', 8734), ('i', 8797), ('o', 7847), ('u', 16385)]

在遍历words列表之后,集合理解将产生一个带有setdefault()方法结果的集合.在这种情况下,set([None])的总和.它还会产生您希望生成列表字典的副作用.

The set comprehension produces a set with the results of the setdefault() method after iterating over the words list. The sum total of set([None]) in this case. It also produces your desired side effect of producing your dict of lists.

它不像直接循环结构那样易读(IMHO),应该避免(IMHO).它不会更短,并且可能不会实质性地更快.这是关于Python的有趣琐事,而不是有用的-恕我直言...也许能赢得赌注?

It is not as readable (IMHO) as the straight looping construct and should be avoided (IMHO). It is no shorter and probably not materially faster. This is more interesting trivia about Python than useful -- IMHO... Maybe to win a bet?

这篇关于通过dict理解追加到列表的dict的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 06:50