Python字典,寻找一个特定的方法

Python字典,寻找一个特定的方法,python,Python,假设我有一个字符串作为键和值作为整数的字典。 其中键是遇到的不同字符串,以及它们遇到的次数 例如:“word”将产生:{“word”:3} 对于变量,我想说: item -> our dictionary string -> word encountered 这个算法很慢,因为通过调用update和string-in-item方法进行两次散列,如果python执行散列来检查item中是否存在字符串,或者在存在键的情况下将值增加1,或者创建键并将值设为1,则散列速度会更快 在Jav

假设我有一个字符串作为键和值作为整数的字典。 其中键是遇到的不同字符串,以及它们遇到的次数

例如:
“word”
将产生:
{“word”:3}

对于变量,我想说:

item -> our dictionary
string -> word encountered


这个算法很慢,因为通过调用
update
string-in-item
方法进行两次散列,如果python执行散列来检查item中是否存在字符串,或者在存在键的情况下将值增加1,或者创建键并将值设为1,则散列速度会更快

在Java中,相应的方法是:

item.merge(string, 1, Integer::sum)
if-else
语句中的代码减少为一行,并再次跳过哈希运算。 只是想知道Python3中是否存在这样的方法


提前谢谢

惯用Python应该是

from collections import defaultdict
d = defaultdict(int)
for word in "word word word".split():
    d[word] += 1

惯用的Python应该是

from collections import defaultdict
d = defaultdict(int)
for word in "word word word".split():
    d[word] += 1

我用不同的方法来填充字典,做了一些时间分析。首先,设置:

import collections, re    
lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
words = re.findall("\w+", lorem.lower())
现在,使用
更新
的方法,或仅使用
+=
,或使用默认值,以及和:

它们都产生相同的结果,尽管最后两个使用了
dict
的子类:

In [41]: f1() == f2() == f3() == f4() == f5()
Out[41]: True
在这里使用
update
是相当浪费的
+=
是最快的,即使在
检查中有
,而
defaultdict
计数器也较短,但速度也较慢

In [42]: %timeit f1()
10000 loops, best of 3: 81.8 us per loop

In [43]: %timeit f2()
10000 loops, best of 3: 24.8 us per loop

In [44]: %timeit f3()
10000 loops, best of 3: 40.8 us per loop

In [45]: %timeit f4()
10000 loops, best of 3: 52.6 us per loop

In [46]: %timeit f5()
10000 loops, best of 3: 104 us per loop
然而,请注意,在这个示例文本中,大多数单词只出现一次,这可能会影响测试。使用
words=words*100
,我们得到了这个结果,使
计数器
的速度变慢,而
defaultdict
的速度变快

In [2]: %timeit f1()
100 loops, best of 3: 8.21 ms per loop

In [3]: %timeit f2()
100 loops, best of 3: 2.76 ms per loop

In [4]: %timeit f3()
100 loops, best of 3: 3.58 ms per loop

In [5]: %timeit f4()
100 loops, best of 3: 2.13 ms per loop

In [6]: %timeit f5()
100 loops, best of 3: 6.11 ms per loop

尽管如此,我个人还是会使用
计数器
,因为运行时间的差异可能不是什么大问题,它是最短的,目的很明确,而且它还提供了一些有用的帮助方法,比如获取最常见的条目等等。

我使用不同的方法来填充字典,做了一些计时分析。首先,设置:

import collections, re    
lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
words = re.findall("\w+", lorem.lower())
现在,使用
更新
的方法,或仅使用
+=
,或使用默认值,以及和:

它们都产生相同的结果,尽管最后两个使用了
dict
的子类:

In [41]: f1() == f2() == f3() == f4() == f5()
Out[41]: True
在这里使用
update
是相当浪费的
+=
是最快的,即使在
检查中有
,而
defaultdict
计数器也较短,但速度也较慢

In [42]: %timeit f1()
10000 loops, best of 3: 81.8 us per loop

In [43]: %timeit f2()
10000 loops, best of 3: 24.8 us per loop

In [44]: %timeit f3()
10000 loops, best of 3: 40.8 us per loop

In [45]: %timeit f4()
10000 loops, best of 3: 52.6 us per loop

In [46]: %timeit f5()
10000 loops, best of 3: 104 us per loop
然而,请注意,在这个示例文本中,大多数单词只出现一次,这可能会影响测试。使用
words=words*100
,我们得到了这个结果,使
计数器
的速度变慢,而
defaultdict
的速度变快

In [2]: %timeit f1()
100 loops, best of 3: 8.21 ms per loop

In [3]: %timeit f2()
100 loops, best of 3: 2.76 ms per loop

In [4]: %timeit f3()
100 loops, best of 3: 3.58 ms per loop

In [5]: %timeit f4()
100 loops, best of 3: 2.13 ms per loop

In [6]: %timeit f5()
100 loops, best of 3: 6.11 ms per loop

尽管如此,我个人还是会使用
计数器
,因为运行时间的差异可能不是什么大问题,它是最短的,目的很明确,而且它还提供了一些有用的辅助方法,比如获取最常见的条目等。

“这个算法很慢,因为散列会发生两次。”是什么让你认为这有任何可测量的效果?因为我在Java中使用了相同的if-else语句,当我切换到merge函数时,我得到了相当大的性能提升,所以我认为在python中也会发生同样的事情。我个人认为,使用
update
会使代码变慢。当您可以只使用
项[string]+=1
项[string]=1
时,为什么要创建一个新的dict来合并到旧dict中呢?或者使用
defaultdict
Counter
。感谢您的建议,我今天刚开始学习python,并且已经开始实现这个:作为一个挑战,我对该语言一无所知。“这个算法很慢,因为散列会发生两次。”是什么让你认为这有任何可测量的效果?因为我在Java中使用了相同的if-else语句,当我切换到merge函数时,我得到了相当大的性能提升,所以我认为在python中也会发生同样的事情。我个人认为,使用
update
会使代码变慢。当您可以只使用
项[string]+=1
项[string]=1
时,为什么要创建一个新的dict来合并到旧dict中呢?或者使用
defaultdict
Counter
。感谢您的建议,我今天刚开始学习python,并且已经开始实现这一点:作为一项挑战,我对该语言一无所知。真正惯用的python应该是
d=collections.Counter(“word.split())
。或者
d=collections.Counter>(re.findall(r“\w”,“word”)中的word.lower())
真正惯用的Python应该是
d=collections.Counter(“word.split())
。或者
d=collections.Counter(re.findall(r“\w”,“word”)中的word.lower())
f2()和f4()都提高了2倍的性能!我选择了f4()因为它没有分支。f2()和f4()都提高了2倍的性能!我选择f4()是因为它没有分支。