jlc*_*lin 174 python dictionary
我想结合OrderedDict(),并defaultdict()从collections一个对象,这应是一个有序的,默认的字典.这可能吗?
zee*_*kay 87
以下(使用此配方的修改版本)适合我:
from collections import OrderedDict, Callable
class DefaultOrderedDict(OrderedDict):
# Source: http://stackoverflow.com/a/6190500/562769
def __init__(self, default_factory=None, *a, **kw):
if (default_factory is not None and
not isinstance(default_factory, Callable)):
raise TypeError('first argument must be callable')
OrderedDict.__init__(self, *a, **kw)
self.default_factory = default_factory
def __getitem__(self, key):
try:
return OrderedDict.__getitem__(self, key)
except KeyError:
return self.__missing__(key)
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
self[key] = value = self.default_factory()
return value
def __reduce__(self):
if self.default_factory is None:
args = tuple()
else:
args = self.default_factory,
return type(self), args, None, None, self.items()
def copy(self):
return self.__copy__()
def __copy__(self):
return type(self)(self.default_factory, self)
def __deepcopy__(self, memo):
import copy
return type(self)(self.default_factory,
copy.deepcopy(self.items()))
def __repr__(self):
return 'OrderedDefaultDict(%s, %s)' % (self.default_factory,
OrderedDict.__repr__(self))
Run Code Online (Sandbox Code Playgroud)
avy*_*ain 39
这是另一种可能性,灵感来自Raymond Hettinger的super()Considered Super,在Python 2.7.X和3.4.X上测试:
from collections import OrderedDict, defaultdict
class OrderedDefaultDict(OrderedDict, defaultdict):
def __init__(self, default_factory=None, *args, **kwargs):
#in python3 you can omit the args to super
super(OrderedDefaultDict, self).__init__(*args, **kwargs)
self.default_factory = default_factory
Run Code Online (Sandbox Code Playgroud)
如果你查看班级的MRO(aka,help(OrderedDefaultDict)),你会看到:
class OrderedDefaultDict(collections.OrderedDict, collections.defaultdict)
| Method resolution order:
| OrderedDefaultDict
| collections.OrderedDict
| collections.defaultdict
| __builtin__.dict
| __builtin__.object
Run Code Online (Sandbox Code Playgroud)
这意味着当一个实例OrderedDefaultDict被初始化时,它会延迟到OrderedDict's init,但是这个实际上会defaultdict在调用之前调用__builtin__.dict它的方法,这正是我们想要的.
Tay*_*ton 20
这是另一种解决方案,可以考虑您的用例是否像我的一样简单,并且您不一定要在代码中添加DefaultOrderedDict类实现的复杂性.
from collections import OrderedDict
keys = ['a', 'b', 'c']
items = [(key, None) for key in keys]
od = OrderedDict(items)
Run Code Online (Sandbox Code Playgroud)
(None是我想要的默认值.)
请注意,如果您的一个要求是使用默认值动态插入新密钥,则此解决方案将不起作用.简单的权衡.
更新3/13/17 - 我了解了这个用例的便利功能.与上面相同,但你可以省略该行items = ...,只是:
od = OrderedDict.fromkeys(keys)
Run Code Online (Sandbox Code Playgroud)
输出:
OrderedDict([('a', None), ('b', None), ('c', None)])
Run Code Online (Sandbox Code Playgroud)
如果您的密钥是单个字符,您只需传递一个字符串:
OrderedDict.fromkeys('abc')
Run Code Online (Sandbox Code Playgroud)
它具有与上述两个示例相同的输出.
您还可以将默认值作为第二个arg传递给OrderedDict.fromkeys(...).
Art*_*yer 15
如果你想要一个不需要课程的简单解决方案,你可以使用或.如果你只是从几个地方获得/设置,比如循环,你可以很容易地设置默认.OrderedDict.setdefault(key, default=None)OrderedDict.get(key, default=None)
totals = collections.OrderedDict()
for i, x in some_generator():
totals[i] = totals.get(i, 0) + x
Run Code Online (Sandbox Code Playgroud)
列表更容易setdefault:
agglomerate = collections.OrderedDict()
for i, x in some_generator():
agglomerate.setdefault(i, []).append(x)
Run Code Online (Sandbox Code Playgroud)
但是如果你多次使用它,最好设置一个类,就像在其他答案中一样.
一个更简单的@zeekay的答案是:
from collections import OrderedDict
class OrderedDefaultListDict(OrderedDict): #name according to default
def __missing__(self, key):
self[key] = value = [] #change to whatever default you want
return value
Run Code Online (Sandbox Code Playgroud)
基于@NickBread的简单优雅的解决方案。具有稍微不同的API来设置工厂,但是好的默认值总是很高兴拥有。
class OrderedDefaultDict(OrderedDict):
factory = list
def __missing__(self, key):
self[key] = value = self.factory()
return value
Run Code Online (Sandbox Code Playgroud)
小智 5
另一个简单的方法是使用字典get方法
>>> from collections import OrderedDict
>>> d = OrderedDict()
>>> d['key'] = d.get('key', 0) + 1
>>> d['key'] = d.get('key', 0) + 1
>>> d
OrderedDict([('key', 2)])
>>>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44177 次 |
| 最近记录: |