python数据类型-6-容器类型-frozenset是线程安全还是进程安全?
一.说明
在python数据类型系列文章中已经介绍了 基础数据类型,容器类型 列表,元组,字典,集合等,今天我们一起来对frozenset 不可变集合 及range函数来进行说明
二.range函数
1.定义
1.用于生成一个不可变的整数序列,常用于循环和迭代;
2.返回的是一个
range
对象,该对象可以用作迭代器;
2.特性
1.惰性生成:
range
不会一次性生成所有数字,而是按需生成,因此更节省内存;2.不可变性:
range
对象是不可变的,一旦创建,不能更改;3.可迭代:
range
对象可以用于循环(如for
循环),可以与其他可迭代对象一起使用。
3.range
函数调用
range
函数有三种常用的调用方式
1.单参数:range(stop)
range(5) #生成 0, 1, 2, 3, 4
2.双参数:range(start, stop)
range(2, 5) #生成 2, 3, 4
3.三参数:range(start, stop, step)
range(1, 10, 2) #生成 1, 3, 5, 7, 9
4.常用的操作和方法
-
转换为列表:可以通过
list()
函数将range
对象转换为列表。
list(range(5)) # 输出: [0, 1, 2, 3, 4]
-
遍历:可以直接用于
for
循环。
for i in range(3):
print(i) # 输出: 0, 1, 2
-
长度:可以使用
len()
函数获取range
对象的长度。
len(range(5)) # 输出: 5
-
索引:
range
对象支持索引。
r = range(5)
print(r[2]) # 输出: 2
5.使用场景
-
循环控制:
range
经常用于for
循环中,控制循环次数。
for i in range(10):
print(i)
- 列表生成:结合列表推导式,可以用来生成特定范围的列表。
squares = [x**2 for x in range(10)] # 生成0到9的平方
-
数据处理:在处理数据集时,可以使用
range
生成索引或切片。
data = [10, 20, 30, 40, 50]
for i in range(len(data)):
print(data[i]) # 遍历数据列表
6.总结
为什么我会把range单独拉出来进行说,因为这个使用实在太频繁了,针对特定语言中频繁出现的东西我们就要理解他掌握他 这就是语言基础的学习,理解并熟练使用 range
能显著提升你的 Python 编程能力。
三.frozenset 不可变集合
frozenset
是 Python 中一种内置的数据结构,用于表示不可变的集合,下面我来对这个集合定义、特性、创建、常用操作和使用方法 使用场景进行说明。
1.定义
1.
frozenset
是一个不可变的集合(set)2.
frozenset
的元素是唯一的且无序的3.
frozenset
一旦创建,就不能修改(即不能添加或删除元素)
2.特性
1.不可变性:
frozenset
创建后不能被更改,保证了数据的安全性。2.唯一性:和普通集合一样,
frozenset
中的元素必须是唯一的。3.无序性:元素没有固定的顺序,无法通过索引访问元素。
4.可哈希性:由于不可变性,
frozenset
可以作为字典的键或存储在其他集合中。
3.创建
可以通过 frozenset()
函数创建一个 frozenset
对象:
# 从可迭代对象创建 frozenset
fs1 = frozenset([1, 2, 3, 4, 5])
fs2 = frozenset('hello') # 只保留唯一字母 {'h', 'e', 'l', 'o'}
my_set = {1, 2, 3}
my_fs_set = frozenset(my_set)
#当作字典的键
my_fs = frozenset([1, 2, 3])
my_dict = {my_fs: "Hello Frozenset!"}
4.常用操作和方法
- 基本操作同集合,但不支持任何改变其内容的操作,但支持集合运算
#查找frozenset的元素
print(1 in fs1) # 输出: True
#作为集合中的元素
set_of_sets = {frozenset([1, 2]), frozenset([3, 4])}
5.使用场景
- 作为字典的键,上面已经举例我不再重复;
- 用来表示一组不变的元素,当你需要存储一些唯一的配置或特征集时,使用
frozenset
可以保证这些特征不被改变。 - 作为集合的元素,上面已经举例我不再重复;
- frozenset是线程安全非进程安全
线程安全: 因为
frozenset
是不可变的,多个线程可以安全地访问它而不需要担心数据的修改。这避免了潜在的竞争条件,特别是在共享数据时。防止意外修改: 在多线程环境中,使用
frozenset
可以防止一个线程意外地改变另一个线程正在使用的数据。高效的哈希:
frozenset
是哈希可用的,这使得它在需要将集合作为键存储到字典中的场景中更高效。
-
frozenset
线程安全的示例:,注意i不会存在被篡改:
import threading
# 定义一个共享的字典
shared_dict = {}
def worker(fset):
# 使用 frozenset 作为字典的键
shared_dict[fset] = sum(fset)
# 创建多个线程
threads = []
for i in range(5):
fset = frozenset([i, i + 1, i + 2])
thread = threading.Thread(target=worker, args=(fset,))
threads.append(thread)
thread.start()
# 等待所有线程完成
for thread in threads:
thread.join()
# 输出结果
for key, value in shared_dict.items():
print(f"{key}: {value}")
'''
frozenset({0, 1, 2}): 3
frozenset({1, 2, 3}): 6
frozenset({2, 3, 4}): 9
frozenset({3, 4, 5}): 12
frozenset({4, 5, 6}): 15
'''
frozenset
非进程安全的示例,无输出结果
from multiprocessing import Process
# 定义一个共享的字典
shared_dict = {}
def worker(fset):
shared_dict[fset] = sum(fset)
if __name__ == "__main__":
# 创建多个进程
processes = []
for i in range(5):
fset = frozenset([i, i + 1, i + 2])
process = Process(target=worker, args=(fset,))
processes.append(process)
process.start()
# 等待所有进程完成
for process in processes:
process.join()
# 输出结果
for key, value in shared_dict.items():
print(f"{key}: {value}")
frozenset
非进程安全的修改版本示例
from multiprocessing import Process, Manager
def worker(fset, shared_dict):
shared_dict[fset] = sum(fset)
if __name__ == "__main__":
manager = Manager()
shared_dict = manager.dict()
# 创建多个进程
processes = []
for i in range(5):
fset = frozenset([i, i + 1, i + 2])
process = Process(target=worker, args=(fset, shared_dict))
processes.append(process)
process.start()
# 等待所有进程完成
for process in processes:
process.join()
# 输出结果
for key, value in shared_dict.items():
print(f"{key}: {value}")
'''
frozenset({0, 1, 2}): 3
frozenset({1, 2, 3}): 6
frozenset({2, 3, 4}): 9
frozenset({3, 4, 5}): 12
frozenset({4, 5, 6}): 15
'''
在python数据类型系列文章我基本已经归纳总结了基本数据类型和容器类型,下一篇是重点,我将重点介绍自定义数据类型Class 或者说叫做面向对象,我就写到这,有不足地方,欢迎大家补充,我来更新!
创作不易,喜欢的话点点关注 点点赞,再次_感谢!