从开始,@ AshwiniChaudhary给出了一个很好的答案来创建一个具有不同set()函数的新(X,Y) = (164,92)
对象:
A = fft2(double(Im)/255.0);
>> Ashifted = fftshift(A);
>> Ashifted(97,158)
ans = 7.4484 - 10.4582i
>> Ashifted(93,165)
ans = 12.1928 - 4.9850i
为了允许用户定义的char / str附加到密钥,我尝试过:
Counter
但它正在返回一个空柜台:
from collections import Counter
class CustomCounter(Counter):
def __setitem__(self, key, value):
if len(key) > 1 and not key.endswith(u"\uE000"):
key += u"\uE000"
super(CustomCounter, self).__setitem__(key, value)
那是因为我错过了from collections import Counter, defaultdict
class AppendedStrCounter(Counter):
def __init__(self, str_to_append):
self._appended_str = str_to_append
super(AppendedStrCounter, self).__init__()
def __setitem__(self, key, value):
if len(key) > 1 and not key.endswith(self._appended_str):
key += self._appended_str
super(AppendedStrCounter, self).__setitem__(tuple(key), value)
中的iter:
>>> class AppendedStrCounter(Counter):
... def __init__(self, str_to_append):
... self._appended_str = str_to_append
... super(AppendedStrCounter, self).__init__()
... def __setitem__(self, key, value):
... if len(key) > 1 and not key.endswith(self._appended_str):
... key += self._appended_str
... super(AppendedStrCounter, self).__setitem__(tuple(key), value)
...
>>> AppendedStrCounter('foo bar bar blah'.split())
AppendedStrCounter()
[OUT]:
__init__()
但是from collections import Counter, defaultdict
class AppendedStrCounter(Counter):
def __init__(self, iter, str_to_append):
self._appended_str = str_to_append
super(AppendedStrCounter, self).__init__(iter)
def __setitem__(self, key, value):
if len(key) > 1 and not key.endswith(self._appended_str):
key += self._appended_str
super(AppendedStrCounter, self).__setitem__(tuple(key), value)
的值是错误的,它应该是2而不是1.
使用>>> AppendedStrCounter('foo bar bar blah'.split(), u'\ue000')
AppendedStrCounter({('f', 'o', 'o', '\ue000'): 1, ('b', 'a', 'r', '\ue000'): 1, ('b', 'l', 'a', 'h', '\ue000'): 1})
以'bar'
正确的方式初始化iter
?
答案 0 :(得分:1)
正如指出的那样
Felix's comment,
collections.Counter
没有记录 如何其__init__
方法添加键或设置值,只记录它。
由于它没有明确地设计用于子类化,最明智的做法是 not 子类化它。
在
collections.abc
模块的存在是为了提供易于子类化的Python内置类型的抽象类,包括dict
(MutableMapping
,以ABC术语表示)。
所以,如果您只需要“Counter
- 类”
(而不是“Counter
的子类,它将满足像isinstance
和issubclass
这样的内置函数,”
您可以创建自己的MutableMapping
,其中包含Counter
,然后是“中间人”初始值设定项以及Counter
添加到典型dict
的三种方法:
import collections
import collections.abc
def _identity(s):
'''
Default mutator function.
'''
return s
class CustomCounter(collections.abc.MutableMapping):
'''
Overrides the 5 methods of a MutableMapping:
__getitem__, __setitem__, __delitem__, __iter__, __len__
...and the 3 non-Mapping methods of Counter:
elements, most_common, subtract
'''
def __init__(self, values=None, *, mutator=_identity):
self._mutator = mutator
if values is None:
self._counter = collections.Counter()
else:
values = (self._mutator(v) for v in values)
self._counter = collections.Counter(values)
return
def __getitem__(self, item):
return self._counter[self._mutator(item)]
def __setitem__(self, item, value):
self._counter[self._mutator(item)] = value
return
def __delitem__(self, item):
del self._counter[self._mutator(item)]
return
def __iter__(self):
return iter(self._counter)
def __len__(self):
return len(self._counter)
def __repr__(self):
return ''.join([
self.__class__.__name__,
'(',
repr(dict(self._counter)),
')'
])
def elements(self):
return self._counter.elements()
def most_common(self, n):
return self._counter.most_common(n)
def subtract(self, values):
if isinstance(values, collections.abc.Mapping):
values = {self._mutator(k): v for k, v in values.items()}
return self._counter.subtract(values)
else:
values = (self._mutator(v) for v in values)
return self._counter.subtract(values)
def main():
def mutator(s):
# Asterisks are easier to print than '\ue000'.
return '*' + s + '*'
words = 'the lazy fox jumps over the brown dog'.split()
# Test None (allowed by collections.Counter).
ctr_none = CustomCounter(None)
assert 0 == len(ctr_none)
# Test typical dict and collections.Counter methods.
ctr = CustomCounter(words, mutator=mutator)
print(ctr)
assert 1 == ctr['dog']
assert 2 == ctr['the']
assert 7 == len(ctr)
del(ctr['lazy'])
assert 6 == len(ctr)
ctr.subtract(['jumps', 'dog'])
assert 0 == ctr['dog']
assert 6 == len(ctr)
ctr.subtract({'the': 5, 'bogus': 100})
assert -3 == ctr['the']
assert -100 == ctr['bogus']
assert 7 == len(ctr)
return
if "__main__" == __name__:
main()
输出(换行,为便于阅读):
CustomCounter({
'*brown*': 1,
'*lazy*': 1,
'*the*': 2,
'*over*': 1,
'*jumps*': 1,
'*fox*': 1,
'*dog*': 1
})
我在初始化程序mutator
中添加了一个仅限关键字的参数,用于存储将真实世界的whatevers转换为“突变”计数版本的函数。
请注意,这可能意味着CustomCounter
不再存储“可哈希的对象”,而是“不能制作变异器barf的可哈希对象”。
此外,如果标准库的Counter
获得了新方法,则必须更新CustomCounter
以“覆盖”它们。
(你可以通过使用来解决这个问题
__getattr__
将任何未知属性传递给self._counter
,但参数中的任何键都将以原始的“未变异”形式传递给Counter
。
最后,正如我之前提到的,如果其他代码专门寻找一个代码,那么实际上不是 collections.Counter
的子类。