杰瑞科技汇

frozenset与set有何本质区别?

Of course! Let's dive deep into Python's frozenset().

frozenset与set有何本质区别?-图1
(图片来源网络,侵删)

What is a frozenset()?

A frozenset() is an immutable, unordered collection of unique elements.

Let's break that down:

  • Set: Like a regular set, it stores unique elements. This means no duplicates are allowed.
  • Unordered: The elements are not stored in any specific order (like a list or tuple). You can't access elements by index (e.g., my_frozenset[0]).
  • Immutable: This is the key difference from a regular set. Once you create a frozenset, you cannot change it. You can't add new elements, remove existing ones, or modify any elements in it.

Think of it as a tuple versus a list. A tuple is an immutable list, and a frozenset is an immutable set.


How to Create a frozenset()

You create a frozenset using the frozenset() constructor. It can take any iterable (like a list, tuple, or a string) as an argument.

frozenset与set有何本质区别?-图2
(图片来源网络,侵删)
# From a list
my_list = [1, 2, 2, 3, 4, 4, 5]
fset_from_list = frozenset(my_list)
print(f"From list: {fset_from_list}") # Output: From list: frozenset({1, 2, 3, 4, 5})
# From a tuple
my_tuple = ('a', 'b', 'c', 'a')
fset_from_tuple = frozenset(my_tuple)
print(f"From tuple: {fset_from_tuple}") # Output: From tuple: frozenset({'c', 'a', 'b'})
# From a string (each character becomes an element)
my_string = "hello"
fset_from_string = frozenset(my_string)
print(f"From string: {fset_from_string}") # Output: From string: frozenset({'o', 'h', 'l', 'e'})
# Creating an empty frozenset
empty_fset = frozenset()
print(f"Empty frozenset: {empty_fset}") # Output: Empty frozenset: frozenset()

Note: If you try to create a frozenset from a set, you get a frozenset object.

my_set = {10, 20, 30}
fset_from_set = frozenset(my_set)
print(f"From set: {fset_from_set}") # Output: From set: frozenset({10, 20, 30})

Key Differences: set vs. frozenset

This table clearly summarizes the differences:

Feature set (Mutable) frozenset (Immutable)
Mutability Mutable. Can be changed after creation. Immutable. Cannot be changed after creation.
Adding Elements my_set.add(4) Not possible. Raises an AttributeError.
Removing Elements my_set.remove(3) or my_set.discard(3) Not possible. Raises an AttributeError.
Modification my_set.update([5, 6]) Not possible. Raises an AttributeError.
Use as Key No. Cannot be a key in a dictionary. Yes. Can be a key in a dictionary or an element in another set.
Hashable No. Not hashable. Yes. Hashable.

Why Use a frozenset? (The Main Use Cases)

The primary reason to use a frozenset is its immutability, which makes it hashable. This unlocks two powerful use cases:

Use Case 1: As a Key in a Dictionary

Regular sets are unhashable and cannot be dictionary keys. Since frozensets are hashable, they can be.

# A regular set cannot be a key
# my_dict = { {1, 2}: "value" }  # TypeError: unhashable type: 'set'
# A frozenset CAN be a key
fset_key = frozenset([1, 2, 3])
my_dict = {
    frozenset([1, 2, 3]): "First Value",
    frozenset([4, 5, 6]): "Second Value"
}
print(my_dict[fset_key]) # Output: First Value

Use Case 2: As an Element in Another Set

You can't put a mutable set inside another set. But you can put an immutable frozenset inside another set.

# A regular set cannot be an element in another set
# outer_set = { {1, 2}, {3, 4} } # TypeError: unhashable type: 'set'
# A frozenset CAN be an element in a set
fset1 = frozenset([1, 2])
fset2 = frozenset([3, 4])
outer_set = {fset1, fset2}
print(outer_set) # Output: {frozenset({1, 2}), frozenset({3, 4})}

Common Operations and Methods

Since frozensets are immutable, they only have read-only methods. Any method that would modify the set is absent.

Operation/Method Description Example (s = frozenset([1, 2, 3]))
len(s) Returns the number of elements in the frozenset. len(s) returns 3
for item in s: Iterates over the elements in the frozenset. for item in s: print(item) prints 1, 2, 3 (order not guaranteed)
item in s Checks if an element is present (membership test). 2 in s returns True
s.issubset(other) Checks if s is a subset of other. s.issubset(frozenset([1, 2, 3, 4])) returns True
s.issuperset(other) Checks if s is a superset of other. s.issuperset(frozenset([1, 2])) returns True
s.isdisjoint(other) Checks if s has no elements in common with other. s.isdisjoint(frozenset([4, 5])) returns True
s.union(other) Returns a new frozenset with elements from both s and other. s.union(frozenset([3, 4, 5])) returns frozenset({1, 2, 3, 4, 5})
s.intersection(other) Returns a new frozenset with elements common to both s and other. s.intersection(frozenset([2, 3, 4])) returns frozenset({2, 3})
s.difference(other) Returns a new frozenset with elements in s but not in other. s.difference(frozenset([2, 3])) returns frozenset({1})
s.symmetric_difference(other) Returns a new frozenset with elements in either s or other but not both. s.symmetric_difference(frozenset([3, 4])) returns frozenset({1, 2, 4})
s.copy() Returns a shallow copy of the frozenset. (Since it's immutable, it's often the same object). s.copy() returns frozenset({1, 2, 3})

Important: Notice that methods like union, intersection, etc., return a new frozenset and do not modify the original one.


When to Choose set vs. frozenset

Choose a set when... Choose a frozenset when...
You need a collection of unique items. You need a collection of unique items that won't change.
You need to frequently add or remove items. You need the collection to be used as a dictionary key.
You are performing set operations (union, intersection) and want to modify the original set. You need the collection to be an element in another set.
Memory is a concern and you don't need hashability. You want a guarantee that the data cannot be altered.

Summary

frozenset() is a specialized but very useful data structure in Python. Its immutability makes it hashable, which is the key to its two main advantages: serving as a dictionary key and an element within another set. When you have data that is a collection of unique items and must remain constant, frozenset is the perfect choice.

分享:
扫描分享到社交APP
上一篇
下一篇