一个“冰冻的口述”是什么?

2024-05-19 12:34:46 发布

您现在位置:Python中文网/ 问答频道 /正文

  • 冰冻的是冰冻的。
  • 冻结的列表可以是元组。
  • 冰冻的听写会是什么?不可变的、可散列的指令

我想它可能类似于collections.namedtuple,但那更像是冻结的密钥dict(半冻结的dict)。不是吗?

“frozendict”应该是一个冻结字典,它应该有keysvaluesget等,并且支持infor

更新:
*在那里:https://www.python.org/dev/peps/pep-0603


Tags: in列表forget字典指令密钥keys
3条回答

Python没有内置的frozendict类型。结果发现这并不经常有用(尽管它可能比frozenset更经常有用)。

需要这种类型的最常见原因是,在对带有未知参数的函数调用进行内存化时。存储dict的可散列等价物(其中值是可散列的)的最常见的解决方案是tuple(sorted(kwargs.iteritems()))

这取决于排序不是有点疯狂。Python不能肯定排序会产生合理的结果。(但它不能保证有更多,所以不要操心太多。)


你可以很容易地做一些包装,工作起来很像一个dict

import collections

class FrozenDict(collections.Mapping):
    """Don't forget the docstrings!!"""

    def __init__(self, *args, **kwargs):
        self._d = dict(*args, **kwargs)
        self._hash = None

    def __iter__(self):
        return iter(self._d)

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

    def __getitem__(self, key):
        return self._d[key]

    def __hash__(self):
        # It would have been simpler and maybe more obvious to 
        # use hash(tuple(sorted(self._d.iteritems()))) from this discussion
        # so far, but this solution is O(n). I don't know what kind of 
        # n we are going to run into, but sometimes it's hard to resist the 
        # urge to optimize when it will gain improved algorithmic performance.
        if self._hash is None:
            self._hash = 0
            for pair in self.iteritems():
                self._hash ^= hash(pair)
        return self._hash

它应该很管用:

>>> x = FrozenDict(a=1, b=2)
>>> y = FrozenDict(a=1, b=2)
>>> x is y
False
>>> x == y
True
>>> x == {'a': 1, 'b': 2}
True
>>> d = {x: 'foo'}
>>> d[y]
'foo'

奇怪的是,尽管我们在python中有很少有用的frozenset,但是仍然没有冻结的映射。这个想法在PEP 416 -- Add a frozendict builtin type中被否决了。这个想法可以在Python3.9中重新讨论,请参见PEP 603 -- Adding a frozenmap type to collections

所以Python2解决方案:

def foo(config={'a': 1}):
    ...

似乎还是有些跛脚:

def foo(config=None):
    if config is None:
        config = default_config = {'a': 1}
    ...

在python3中,您可以选择this

from types import MappingProxyType

default_config = {'a': 1}
DEFAULTS = MappingProxyType(default_config)

def foo(config=DEFAULTS):
    ...

现在,默认的配置可以动态更新,但是在您希望它不可变的地方保持不变,方法是传递代理。

因此default_config中的更改将按预期更新DEFAULTS,但不能写入映射代理对象本身。

诚然,它与“不可变的、散列的dict”并不完全相同,但考虑到我们可能需要一个frozendict的相同类型的用例,它是一个不错的替代品。

假设字典的键和值本身是不可变的(例如字符串),那么:

>>> d
{'forever': 'atones', 'minks': 'cards', 'overhands': 'warranted', 
 'hardhearted': 'tartly', 'gradations': 'snorkeled'}
>>> t = tuple((k, d[k]) for k in sorted(d.keys()))
>>> hash(t)
1524953596

相关问题 更多 >