假设我有一大堆单词。例如:
>>> 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...}
对于Python 2.7,3+dict的理解,有没有办法做到这一点?换句话说,在构建dict时,dict理解语法是否可以附加由键表示的列表?
即:
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% --
带默认dict的直循环最快,其次是set comprehension和带setdefault
的循环。
谢谢你的建议!
无听写理解被设计为在每次迭代中生成不重叠的键;它们不支持聚合。对于这个特定的用例,循环是有效地(在线性时间内)完成任务的正确方法。
听写理解是不可能的(至少是容易或直接的)。
在理解集合或列表的情况下,可能但可能滥用语法:
印刷品:
集合理解在遍历
words
列表之后生成一个集合,其中包含setdefault()
方法的结果。本例中set([None])
的总和。它也会产生你想要的副作用,产生你的名言列表。它不像直循环结构那样可读(IMHO),应该避免(IMHO)。它不短,也可能不快。这是关于Python的有趣的琐事,而不是有用的——IMHO。。。也许是为了赌赢?
我会用
filter
:相关问题 更多 >
编程相关推荐