frozenset() - 何时可以使用它们的示例

Pho*_*nix 5 python set python-3.x

我可以提供一些简单的例子,说明何时使用冷冻装置将是帮助我更好地理解这个概念的最佳选择.

Mar*_*ers 12

frozenset()对象可以用来作为字典键和作为值的内部set()frozenset()对象,其中set对象不能.set()值是可变的并且不可清除,frozenset()值是不可变的并且是可清除的.

他们要set的对象是什么tuple对象是list对象.

演示:

>>> s = set([1, 2])
>>> fs = frozenset(s)
>>> adict = {}
>>> adict[s] = 42   # a set as key does not work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> adict[fs] = 42  # a frozenset as key works
>>> s.add(s)        # a set as value in a set does not work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> s.add(fs)       # a frozenset as value in a set works
Run Code Online (Sandbox Code Playgroud)

最近的Python版本将优化set文字的使用:

if somevar in {'foo', 'bar', 'baz'}:
Run Code Online (Sandbox Code Playgroud)

通过frozenset()使用字节码存储常量:

>>> import dis
>>> dis.dis(compile("if somevar in {'foo', 'bar', 'baz'}: pass", '<stdin>', 'exec'))
  1           0 LOAD_NAME                0 (somevar) 
              3 LOAD_CONST               4 (frozenset({'foo', 'baz', 'bar'})) 
              6 COMPARE_OP               6 (in) 
              9 POP_JUMP_IF_FALSE       15 
             12 JUMP_FORWARD             0 (to 15) 
        >>   15 LOAD_CONST               3 (None) 
             18 RETURN_VALUE         
Run Code Online (Sandbox Code Playgroud)

因为无论如何都不能改变集合文字; 这使得使用集合来测试非常有效.常规set()不能以这种方式存储,因为这将允许您改变与字节对象一起存储的常量.


Ben*_*Ben 5

为了补充 Martijn 所说的,我经常使用它们作为缓存键。例如,一个可以关闭的 memoize 装饰器(args, frozenset(kwargs.items())