文章目录
- python 中有哪些类型或数据结构
- 什么是有序和无序
- 什么是可变和不可变
- 字典中,什么类型可以当做key去使用
- 闭包是什么
- 装饰器是什么
python 中有哪些类型或数据结构
在 Python 中,有多种类型和数据结构可用于存储和组织数据。以下是一些常见的类型和数据结构:
- 数值型(Numeric Types):用于表示数字的类型,包括整数(
int
)、浮点数(float
)和复数(complex
)等。 - 字符串(String):用于表示文本数据的类型,由一系列字符组成,使用单引号或双引号括起来。
- 列表(List):可变的有序序列,可以包含不同类型的元素。使用方括号括起,元素之间使用逗号分隔。
- 元组(Tuple):不可变的有序序列,与列表类似,但元素不可修改。使用圆括号括起,元素之间使用逗号分隔。
- 集合(Set):无序的数据集合,没有重复元素,支持基本的集合操作,如并集、交集、差集等。
- 字典(Dictionary):无序的键值对集合,每个元素由一个唯一键和对应的值组成,用大括号括起,键和值之间使用冒号分隔。
- 布尔型(Boolean):表示真或假的值,只有两个取值:
True
和False
。 - 零值(None):表示空和缺失的特殊对象,常用于表示一个没有值的变量。
除了上述基本类型和数据结构,Python 还提供了许多其他类型和数据结构,如字节串(bytes
)、字节数组(bytearray
)、范围(range
)、枚举(enum
)等。此外,还可以使用模块和库来引入自定义的数据结构和类型,以满足特定的编程需求。
这些类型和数据结构在 Python 中非常常用,开发者可以根据具体的需求选择合适的类型来存储和操作数据。
什么是有序和无序
有序(Ordered)和无序(Unordered)是描述数据的排列方式或组织形式的概念。
有序指的是数据的元素按照一定的顺序进行排列,并且这个顺序是可以预测和可靠的。在有序数据中,元素之间存在一种明确的关系或结构。通过索引或位置,我们可以访问和获取特定位置的元素。常见的有序数据结构包括列表(List)、元组(Tuple)、字符串(String)等。
例如,一个列表 [1, 2, 3, 4]
是有序的,其中元素按照从左到右的顺序排列。我们可以使用索引来访问特定位置的元素,如 my_list[0]
表示获取列表中的第一个元素。
相反,无序指的是数据的元素没有明确的顺序或排列方式。元素在容器中不存在特定的位置或索引,因此不能准确地预测或确定元素的顺序。常见的无序数据结构包括集合(Set)、字典(Dictionary)等。
例如,一个集合 {1, 2, 3, 4}
是无序的,其中元素之间没有特定的顺序。我们不能使用索引来获取某个元素,只能通过成员关系判断一个元素是否存在于集合中。
需要注意的是,有序和无序仅描述了数据的排列方式,并不代表数据的值或内容的有序或无序。在有序数据结构中,元素的值仍然可以是无序的,而在无序数据结构中,元素的值也可以按一定的方式进行组织和排序。
什么是可变和不可变
可变(Mutable)和不可变(Immutable)是描述数据对象是否可以被修改的概念。
可变指的是数据对象的值可以被修改或改变。这意味着在对可变对象进行操作时,可以更改其内部的状态或内容,而对象的身份或标识不会改变。可变对象可以添加、删除或更新其元素。常见的可变对象包括列表(List)、字典(Dictionary)、集合(Set)等。
例如,对于一个列表 [1, 2, 3]
,我们可以执行操作来添加一个新元素,如 my_list.append(4)
,此时该列表就会改变并包含新的元素。
相反,不可变指的是数据对象的值不能被修改或改变。当尝试修改不可变对象时,实际上是创建了一个新的对象,而原始对象保持不变。不可变对象的值在创建后就无法更改。常见的不可变对象包括整数(int)、浮点数(float)、字符串(string)、元组(tuple)等。
例如,对于一个字符串 "Hello"
,我们不能直接在原始字符串上进行修改,但可以通过创建新的字符串来进行操作,如 new_string = my_string + " World"
,此时会生成一个新的字符串对象。
不可变对象的优点包括更安全和可靠。由于不可变对象不可更改,因此在多个引用之间共享时,不会出现意外的副作用或不一致的结果。
需要注意的是,对一个变量重新赋值并不改变原始对象的可变性。例如,对一个可变对象重新赋值后,该变量引用了一个新的对象,但原始对象仍然存在于内存中,因此它的内部状态可以被修改。而对一个不可变对象重新赋值时,会创建一个新的对象,原始对象也不会改变。
a = [1, 2, 3, 4]
print(id(a)) # 1534040865600a.append(5)
print(id(a)) # 1534040865600c = a
print(id(c)) # 2394275183424b = a.copy()
print(id(b)) # 2989132595456print(a == b) # Trueprint(a is b) # False
当你修改列表的时候,他的id不会改变。这就是可变
a = "cxk"
print(id(a)) # 2874637880752
a += "d"
print(a, id(a)) # 2874637880560
当你修改元组就压根不能修改
字符串可以修改,但是改后id会变,这就是不可变
字典中,什么类型可以当做key去使用
在字典中,只有不可变的数据类型可以作为键(key)使用。这是因为字典的键需要具备哈希(hash)的特性,而哈希值是通过键的内容计算得到的。
以下是一些常见的可作为字典键的数据类型:
- 整数(int):整数是不可变的,可以作为字典的键。
- 浮点数(float):浮点数也是不可变的,可以作为字典的键。
- 字符串(str):字符串是不可变的,常用作字典的键。
- 元组(tuple):元组是不可变的,因此可以作为字典的键。但要注意,元组只有当其内部的元素也都是不可变类型时,才能作为字典的键。
以下是一些不能作为字典键的数据类型:
- 列表(list):列表是可变的,因此不能作为字典的键。
- 字典(dictionary):字典本身是可变的,所以不能作为字典的键。
- 集合(set):集合是可变的,不能作为字典的键。
需要注意的是,虽然字符串和整数是可哈希的,并且可以作为字典的键,但相同内容的字符串对象或整数对象,在内存中只有一个实例,并且具有相同的哈希值。这意味着当使用相同内容的字符串或整数作为键时,它们会被视为相同的键,并且只能在字典中出现一次。如果尝试使用列表、字典或集合作为键,则会引发 TypeError 异常。
闭包是什么
闭包(Closure)是指在一个函数内部定义的函数,并且该内部函数可以访问外部函数的变量、参数以及定义的其他函数。闭包可以捕获外部函数的状态,包括局部变量、参数等,并将其保存起来,使得外部函数的状态在内部函数被调用时仍然保持有效。
在Python中,当一个内部函数引用了外部函数的变量时,就会形成一个闭包。闭包函数可以像普通函数一样被调用,并且可以访问外部函数的变量,即使外部函数已经执行结束。
下面是一个简单的示例:
pythonCopy Codedef outer_function(x):def inner_function(y):return x + yreturn inner_functionclosure = outer_function(10)
print(closure(5)) # 输出 15
上述代码中,outer_function
是一个外部函数,它接受一个参数 x
,并在内部定义了 inner_function
。inner_function
可以访问外部函数的参数 x
,并返回 x + y
的结果。
通过调用 outer_function(10)
,我们得到一个闭包 closure
,它绑定了 x
的值为 10。然后,我们再次调用 closure(5)
,实际上是调用了内部函数 inner_function
,并传入参数 y
值为 5。最终的结果是 10 + 5,即 15。
闭包在编程中有一些应用场景,其中一个常见的是延迟计算。通过使用闭包,我们可以将一些状态或变量的绑定延迟到函数被调用的时候,从而实现一些特定的功能,例如惰性求值、缓存等。
需要注意的是,在使用闭包时,要注意处理外部函数变量的生命周期,避免出现意外的问题,如变量泄漏等。
装饰器是什么
装饰器利用了闭包中内部函数可以访问外部函数参数的特征 和 函数可以当做参数传递的特征实现。
def logger(func):def wrapper(*args, **kwargs):print("Function {}() is called with arguments: {}, {}".format(func.__name__, args, kwargs))result = func(*args, **kwargs)print("Function {}() returns: {}".format(func.__name__, result))return resultreturn wrapper@logger
def add(a, b):return a + badd(2, 3) # 输出: Function add() is called with arguments: (2, 3), {}# Function add() returns: 5