python - 通过解包计算从 python 字典中读取的内容

标签 python dictionary python-3.5

我有兴趣计算对字典值的访问次数。我不确定如何在柜台中包括字典拆包。有什么建议吗?

from collections import defaultdict

class LDict(dict):
    def __init__(self, *args, **kwargs):
        '''
        This is a read-counting dictionary
        '''
        super().__init__(*args, **kwargs)
        self._lookup = defaultdict(lambda : 0)

    def __getitem__(self, key):
        retval = super().__getitem__(key)
        self._lookup[key] += 1
        return retval

    def __setitem__(self, key, value):
        super().__setitem__(key, value)
        self._lookup[key] = self._lookup.default_factory()

    def __delitem__(self, key):
        super().__delitem__(self, key)
        _ = self._lookup[key]
        del self._lookup[key]

    def list_unused(self):
        return [key for key in self if self._lookup[key] == 0]

l = LDict(a='apple', b='bugger')

print({**l, **l})
print(l.list_unused())
_ = l['a']
print(l.list_unused())

最佳答案

您需要覆盖更多方法。访问不是通过 __getitem__() 集中:copy()items() 等其他方法。无需通过 __getitem()__ 即可访问 key 。我假设 ** 运算符使用 items(),但您需要处理所有方法以跟踪每次访问。在许多情况下,您将不得不做出判断。例如,__repr__() 算作一次访问吗?返回的字符串包含格式化的每个键和值,所以我认为它确实如此。

我建议覆盖所有这些方法,因为您还必须对分配进行簿记。

def __repr__(self):
def __len__(self):
def __iter__(self):
def clear(self):
def copy(self):
def has_key(self, k):
def update(self, *args, **kwargs):
def keys(self):
def values(self):
def items(self):

编辑:显然这里有一个与您的实现直接相关的重要警告。如果 LDict 扩展 dict,则在字典解包期间不会调用这些方法中的任何一个 { **l, **l}

显然你可以听从建议here但是,并在不扩展 dict 的情况下实现 LDict。这对我有用:

from collections import MutableMapping

class LDict(MutableMapping):
    def __init__(self, *args, **kwargs):
        '''
        This is a read-counting dictionary
        '''
        self._lookup = defaultdict(lambda : 0)
        self.data = {}
        if kwargs:
            self.data.update(kwargs)

    def __getitem__(self, key):
        retval = self.data[key]
        self._lookup[key] += 1
        return retval

    def __setitem__(self, key, value):
        self.data[key] = value
        self._lookup[key] = self._lookup.default_factory()

    def __delitem__(self, key):
        del self.data[key]
        _ = self._lookup[key]
        del self._lookup[key]

    def items(self):
        print('items is being called!')
        yield from self.data.items()

    def __iter__(self):
        print('__iter__ is being called!')
        yield from self.data

    def __len__(self):
        return len(self.data)    


    def list_unused(self):
        return [key for key in self if self._lookup[key] == 0]

l = LDict(a='apple', b='bugger')

print({**l, **l})
print(l.list_unused())
_ = l['a']
print(l.list_unused())

产生输出:

__iter__ is being called!
__iter__ is being called!
{'b': 'bugger', 'a': 'apple'}
__iter__ is being called!
[]
__iter__ is being called!
[]

(我只实现了最低限度以使示例正常工作,如果您希望计数正确,我仍然建议实现我列出的方法集!)

所以我想你的问题的答案是你必须

  1. 实现__iter__(self)方法
  2. 不要继承dict()

关于python - 通过解包计算从 python 字典中读取的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47086735/

相关文章:

api - 谷歌词典 API 不起作用——还有其他解决方案吗?

python - 如何在Python3中合并两个不相等的输入/列表

python - Nose 测试和类方法

python - 了解 Linux Mint 中的扭曲安装

python - OpenCV 3.0 线迭代器

python - Python 文件权限中的 Zipfile

python - 可编辑的 QTableView 和 Pandas 不能正常工作

ruby-on-rails - 在 Rails 中根据英语词典验证单词?

java - 是否有维护插入顺序的 IdentityHashMap 实现?

windows-10 - 如何在 Windows 上安装 pyldap 包?