我用timeit获得了非常令人惊讶的结果,有人可以告诉我,如果我做错了吗?我使用的是Python 2.7.
这是文件speedtest_init.py的内容:
import random
to_count = [random.randint(0, 100) for r in range(60)]
Run Code Online (Sandbox Code Playgroud)
这些是speedtest.py的内容:
__author__ = 'BlueTrin'
import timeit
def test_init1():
print(timeit.timeit('import speedtest_init'))
def test_counter1():
s = """\
d = defaultdict(int);
for i in speedtest_init.to_count:
d[i] += 1
"""
print(timeit.timeit(s, 'from collections import defaultdict; import speedtest_init;'))
def test_counter2():
print(timeit.timeit('d = Counter(speedtest_init.to_count);', 'from collections import Counter; import speedtest_init;'))
if __name__ == "__main__":
test_init1()
test_counter1()
test_counter2()
Run Code Online (Sandbox Code Playgroud)
控制台输出是:
C:\Python27\python.exe C:/Dev/codility/chlorum2014/speedtest.py
2.71501962931
65.7090444503
91.2953839048
Process finished with exit code 0
Run Code Online (Sandbox Code Playgroud)
我认为默认情况下timeit()运行代码的1000000倍,所以我需要将时间除以1000000,但令人惊讶的是Counter慢于defaultdict().
这是预期的吗?
编辑:
使用dict也比defaultdict(int)更快: …
这个让我大吃一惊.鉴于以下字典:
d = {"a":{"b":{"c":"winning!"}}}
Run Code Online (Sandbox Code Playgroud)
我有这个字符串(来自外部来源,我不能改变这个比喻).
k = "a.b.c"
Run Code Online (Sandbox Code Playgroud)
我需要确定字典是否有密钥 'c',所以如果没有,我可以添加它.
这可以游戏地检索点符号值:
reduce(dict.get, key.split("."), d)
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何'减少'has_key检查或类似的东西.
我的最终问题是:给定"abcde",我需要创建字典中所需的所有元素,但如果它们已经存在则不要踩它们.如果有人知道做出这一切的真正方式,那么你将成为我的英雄.
我想尝试做类似的事情:
from collections import defaultdict
import hashlib
def factory():
key = 'aaa'
return { 'key-md5' : hashlib.md5('%s' % (key)).hexdigest() }
a = defaultdict(factory)
print a['aaa']
Run Code Online (Sandbox Code Playgroud)
(实际上,我之所以需要访问工厂中的密钥,不是为了计算md5,而是出于其他原因;这只是一个例子)
正如你所看到的,在工厂里我无法访问密钥:我只是强迫它,这没有任何意义.
是否可以以defaultdict我可以在工厂中访问密钥的方式使用?
我运行了以下代码:
from collections import defaultdict
lst = list(range(0,5))
d = defaultdict(lst)
Run Code Online (Sandbox Code Playgroud)
我收到了这个错误:
TypeError: first argument must be callable or None
Run Code Online (Sandbox Code Playgroud)
请帮忙
我想用两个创建一个类:collections.OrderedDict和collections.DefaultDict.这样我就可以获得一个有序的字典,并为访问的现有密钥设置一个默认值.有什么方法可以做到这一点?
我的解决方案是围绕我上面提到的两个类创建另一个类.由于我认为每个类中的方法具有相同的名称,这会导致错误吗?
from collections import defaultdict, OrderedDict
class owndic(OrderedDict, defaultdict):
pass
Run Code Online (Sandbox Code Playgroud)
生产
TypeError: multiple bases have instance lay-out conflict
Run Code Online (Sandbox Code Playgroud)
干杯!
有谁知道Python中是否存在无限可嵌套字典的标准类?
我发现自己重复这种模式:
d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
d['abc']['def']['xyz'] += 1
Run Code Online (Sandbox Code Playgroud)
如果我想添加"另一层"(例如d['abc']['def']['xyz']['wrt']),我必须定义另一个defaultdicts嵌套.
为了概括这种模式,我编写了一个简单的类来覆盖__getitem__自动创建下一个嵌套字典.
例如
d = InfiniteDict(('count',0),('total',0))
d['abc']['def']['xyz'].count += 0.24
d['abc']['def']['xyz'].total += 1
d['abc']['def']['xyz']['wrt'].count += 0.143
d['abc']['def']['xyz']['wrt'].total += 1
Run Code Online (Sandbox Code Playgroud)
但是,有没有人知道这个想法的预先实现?我试过谷歌搜索,但我不确定这会被称为什么.
我首次尝试将collections模块中两个字典的功能组合在一起,创建一个继承它们的类:
from collections import OrderedDict, defaultdict
class DefaultOrderedDict(defaultdict, OrderedDict):
def __init__(self, default_factory=None, *a, **kw):
super().__init__(default_factory, *a, **kw)
Run Code Online (Sandbox Code Playgroud)
但是,我无法为此词典分配项目:
d = DefaultOrderedDict(lambda: 0)
d['a'] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.3/collections/__init__.py", line 64, in __setitem__
self.__map[key] = link = Link()
AttributeError: 'DefaultOrderedDict' object has no attribute '_OrderedDict__map'
Run Code Online (Sandbox Code Playgroud)
实际上,关于如何创建类似对象的这个问题有通过扩展OrderedDict类并手动重新实现所提供的其他方法来实现它的答案defaultdict.使用多重继承会更清晰.为什么不起作用?
python multiple-inheritance ordereddictionary python-3.x defaultdict
有没有\你如何建立一个相当的python非常有用collections.defaultdict?
想象一下这种容器的用法:
>>> a = collections.defaultlist(0)
>>> a[2]=7
>>> a[4]='x'
>>> a
[0,0,7,0,'x']
Run Code Online (Sandbox Code Playgroud)
更新:我添加了一个后续问题,为此构造添加更多功能
我正在为性能很重要的应用程序编写代码.我想知道为什么defaultdict似乎更快setdefault.
我希望能够使用setdefault,主要是因为我不喜欢嵌套的打印输出defaultdict(参见下面的实现).
在我的代码中,我需要测试是否element_id已经是dict的关键.
以下是我正在测试的两个函数:
def defaultdictfunc(subcases,other_ids,element_ids):
dict_name= defaultdict(lambda: defaultdict(lambda: defaultdict(dict)))
for subcase in subcases:
for other_id in other_ids:
for element_id in element_ids:
if element_id in dict_name[subcase][other_id]:
# error duplicate element_id
pass
else:
dict_name[subcase][other_id][element_id]=0
return dict_name
def setdefaultfunc(subcases,other_ids,element_ids):
dict_name={}
for subcase in subcases:
for other_id in other_ids:
for element_id in element_ids:
if element_id in dict_name.setdefault(subcase,{}).setdefault(other_id,{}):
# error duplicate element_id
pass
else:
dict_name[subcase][other_id][element_id]=0
return dict_name
Run Code Online (Sandbox Code Playgroud)
IPython输入输出:
In [1]: from numpy.random import randint …Run Code Online (Sandbox Code Playgroud) 我defaultdict用来存储数百万个短语,所以我的数据结构看起来像mydict['string'] = set(['other', 'strings']).它似乎适用于较小的套装但是当我击中任何超过1000万个按键时,我的程序只是崩溃了有用的信息Process killed.我知道defaultdict内存很重,但是有一个使用defaultdicts 存储的优化方法还是我必须查看其他数据结构,如numpy数组?
谢谢
defaultdict ×10
python ×10
dictionary ×4
nested ×2
python-2.7 ×2
python-3.x ×2
class ×1
collections ×1
containers ×1
counter ×1
infinite ×1
large-data ×1
numpy ×1
setdefault ×1
timeit ×1