1. 空值
在 Python 中,空值(Null)通常表示“无值”或“未定义的值”。Python 使用 None 来表示空值。
变量初始化
a = None
print(a) # 输出: None
判断是否为空
判断一个变量是否为 None,推荐使用 is 运算符,而不是 ==,因为 is 会检查对象的身份。
a = None
if a is None:
print("a is None") # 输出: a is None
print(a == 0) # 输出: False
print(a == '') # 输出: False
print(a == False) # 输出: False
print(a == None) # 输出: True
函数返回空值
如果函数没有明确的返回语句,Python 会自动返回 None。
def foo():
pass # 没有返回值
result = foo()
print(result) # 输出: None
默认参数值
def greet(name=None):
if name is None:
name = 'Guest'
print(f"Hello, {name}!")
greet() # 输出: Hello, Guest!
greet('Alice') # 输出: Hello, Alice!
2. 布尔
在 Python 中,布尔类型 (bool) 是一种表示真或假的数据类型。布尔类型只有两个可能的值:
True:表示真。False:表示假。
# 定义布尔变量
a = True
b = False
print(a) # 输出: True
print(b) # 输出: False
真假值
会被视为假值的内置对象:
- 被定义为假值的常量:
None和False。 - 任何数值类型的零:
0,0.0,0j,Decimal(0),Fraction(0, 1) - 空的序列和多项集:
'',(),[],{},set(),range(0)
# 假值常量
print(bool(None)) # False
print(bool(False)) # False
# 数值类型的零
print(bool(0)) # False
print(bool(0.0)) # False
print(bool(0j)) # False
from decimal import Decimal
print(bool(Decimal(0))) # False
from fractions import Fraction
print(bool(Fraction(0, 1))) # False
# 空的序列和多项集
print(bool('')) # False,空字符串
print(bool(())) # False,空元组
print(bool([])) # False,空列表
print(bool({})) # False,空字典
print(bool(set())) # False,空集合
print(bool(range(0))) # False,空 range
运算符
Python 提供了以下布尔运算符来执行逻辑运算:
and:与运算,只有两个条件都为真时,结果才为真。or:或运算,只有两个条件都为假时,结果才为假。not:非运算,取反。
# 逻辑运算
a = True
b = False
print(a and b) # 输出: False,两个条件都为真时结果才为真
print(a or b) # 输出: True,两个条件中有一个为真,结果为真
print(not a) # 输出: False,取反
条件判断
布尔类型常用于控制流程结构,如 if 语句:
if a:
print("a 是 True")
else:
print("a 是 False")
3. 数字
整数
整数可以是正整数、负整数或零,且没有小数部分。
a = 10 # 正整数
b = -5 # 负整数
c = 0 # 零
在 Python 中,int 类型的整数是没有大小限制的,直到你的机器内存不足为止。Python 会自动调整整数的大小。
large_int = 1234567890123456789012345678901234567890
print(large_int) # 输出一个非常大的整数
进制
进制表示
Python 支持不同进制的整数表示:
- 十进制(默认):普通的数字表示。
- 二进制:使用
0b或0B开头。 - 八进制:使用
0o或0O开头。 - 十六进制:使用
0x或0X开头。
# 十进制
decimal = 42
# 二进制
binary = 0b101010 # 42
# 八进制
octal = 0o52 # 42
# 十六进制
hexadecimal = 0x2A # 42
print(decimal, binary, octal, hexadecimal) # 42 42 42 42
进制转换
从十进制转换为其他进制
Python 提供了内置函数来将十进制整数转换为二进制、八进制和十六进制。
bin():将整数转换为二进制表示(返回字符串)。oct():将整数转换为八进制表示(返回字符串)。hex():将整数转换为十六进制表示(返回字符串)。
# 十进制数
decimal = 42
# 转换为二进制
binary = bin(decimal) # '0b101010'
print(binary)
# 转换为八进制
octal = oct(decimal) # '0o52'
print(octal)
# 转换为十六进制
hexadecimal = hex(decimal) # '0x2a'
print(hexadecimal)
说明:
-
bin()、oct()和hex()都会返回带有前缀的字符串(分别是0b、0o和0x),表示该数字的进制。 -
若需要去掉前缀,可以使用字符串切片:
binary = bin(decimal)[2:] # '101010' octal = oct(decimal)[2:] # '52' hexadecimal = hex(decimal)[2:] # '2a'
- 从其他进制转换为十进制
可以使用 Python 的 int() 函数将一个特定进制的字符串转换为十进制整数。int() 函数需要指定数字字符串的进制。
int(string, base):将指定进制的数字字符串转换为十进制整数,base是数字字符串的进制。
# 二进制转十进制
binary_str = '101010'
decimal_from_binary = int(binary_str, 2)
print(decimal_from_binary) # 42
# 八进制转十进制
octal_str = '52'
decimal_from_octal = int(octal_str, 8)
print(decimal_from_octal) # 42
# 十六进制转十进制
hexadecimal_str = '2a'
decimal_from_hexadecimal = int(hexadecimal_str, 16)
print(decimal_from_hexadecimal) # 42
- 其他进制的转换
你也可以进行进制之间的直接转换,先转换为十进制,再转换为目标进制。例如,二进制转十六进制:
# 二进制转十进制
binary_str = '101010'
decimal = int(binary_str, 2)
# 十进制转十六进制
hexadecimal = hex(decimal)[2:] # '2a'
print(hexadecimal) # 2a
浮点数
在 Python 中,浮点数(float)是表示带有小数点的数字的类型。浮点数可以用于表示实数(有小数部分的数字),并支持各种算术运算、比较和转换。
表示
浮点数可以是正数、负数或零,且包含小数部分。浮点数也可以通过科学计数法(e 或 E)表示。
# 普通浮点数
a = 3.14
b = -2.5
c = 0.0
# 科学计数法表示
d = 1.23e4 # 1.23 × 10^4 = 12300.0
e = 5E-3 # 5 × 10^-3 = 0.005
精度问题
浮点数在计算机中使用有限的位数表示,因此在表示一些十进制数时,可能会发生精度丢失。比如:
a = 0.1 + 0.2
print(a) # 0.30000000000000004
这种现象是浮点数表示精度有限造成的。在实际使用中,通常会将浮点数四舍五入到所需的位数。
由于浮点数的精度问题,直接比较两个浮点数是否相等可能会出现问题。为了避免这种情况,通常使用 math.isclose() 函数来比较两个浮点数是否相等,允许一定的误差范围。
import math
a = 0.1 + 0.2
b = 0.3
# 使用 isclose 来比较浮点数
print(math.isclose(a, b)) # True
常见方法
-
round():四舍五入到指定小数位数。value = 3.14159 rounded_value = round(value, 2) # 保留两位小数 print(rounded_value) # 3.14 -
float():将其他类型(如整数、字符串)转换为浮点数。integer_value = 10 float_value = float(integer_value) # 转换为浮点数 print(float_value) # 10.0 str_value = "12.34" float_value = float(str_value) # 转换为浮点数 print(float_value) # 12.34 -
isnan():检查浮点数是否是NaN(不是一个数字)。import math nan_value = math.nan print(math.isnan(nan_value)) # True -
inf和-inf:浮点数的正无穷大和负无穷大。positive_infinity = float('inf') negative_infinity = float('-inf') print(positive_infinity > 10000) # True print(negative_infinity < -10000) # True
复数
在 Python 中,复数(complex)是一种表示复数的类型。复数由实部和虚部组成,虚部以 j 结尾。
创建
a = 1 + 2j
b = complex(1, 2)
访问实部和虚部
a = 1 + 2j
print(a.real) # 输出: 1.0
print(a.imag) # 输出: 2.0
常见方法
conjugate():返回复数的共轭复数。
a = 1 + 2j
print(a.conjugate()) # 输出: (1-2j)
4. 字符串
创建
以下常见的字符串创建方式:
1. 使用单引号 (') 或双引号 (")
str1 = 'Hello'
str2 = "World"
- 单引号和双引号功能一样,可以根据需求选择。
2. 使用三引号(''' 或 """)
三引号可以用于创建多行字符串或包含换行符的字符串。
str3 = '''Hello
World'''
str4 = """This is
a multi-line string"""
- 使用三引号时,字符串可以跨越多行,并且可以保留换行符。
3. 使用 str() 函数
str5 = str(123)
str()函数用于将其他数据类型转换为字符串,通常用于将数字、列表等转换为字符串。
4. 使用 join() 方法
str6 = ''.join(['H', 'e', 'l', 'l', 'o'])
join()是字符串对象的方法,常用于将序列中的元素连接成一个字符串。
字符串格式化
在 Python 中,除了使用 format 和 format_map 进行字符串格式化外,还可以使用其他几种方式来进行字符串格式化。以下是常见的几种字符串格式化方法的总结:
百分号 (%) 格式化
这是 Python 2 中常用的格式化方法,在 Python 3 中依然有效。其基本语法为 "%格式化符号" % 值。
name = 'Alice'
age = 25
text = 'Hello, %s! You are %d years old.' % (name, age)
print(text) # 输出 'Hello, Alice! You are 25 years old.'
f-字符串(格式化字符串字面量)
从 Python 3.6 开始,支持使用 f-字符串(formatted string literals)。它通过在字符串前加 f 或 F,并直接在字符串中嵌入表达式进行格式化。
name = 'Alice'
age = 25
text = f'Hello, {name}! You are {age} years old.'
print(text) # 输出 'Hello, Alice! You are 25 years old.'
str.format()
str.format() 是 Python 3 中推荐的格式化方法,它比 % 格式化更强大且灵活,支持位置参数和关键字参数。
name = 'Alice'
age = 25
text = 'Hello, {}! You are {} years old.'.format(name, age)
print(text) # 输出 'Hello, Alice! You are 25 years old.'
支持键值对:
text = 'Hello, {name}! You are {age} years old.'.format(name='Alice', age=25)
print(text) # 输出 'Hello, Alice! You are 25 years old.'
str.format_map()
format_map() 方法与 str.format() 类似,不过它通过一个字典来提供数据,替换字符串中的字段。
text = 'Hello, {name}! You are {age} years old.'
text = text.format_map({'name': 'Alice', 'age': 25})
print(text) # 输出 'Hello, Alice! You are 25 years old.'
Template 类(string.Template)
string.Template 提供了一种简化的字符串格式化方式,适用于简单的插值需求。它通过 $ 符号来表示变量。
from string import Template
# 示例
template = Template('Hello, $name! You are $age years old.')
text = template.substitute(name='Alice', age=25)
print(text) # 输出 'Hello, Alice! You are 25 years old.'
编码与解码
在 Python 中,编码和解码通常是指将字符串与字节数据之间的转换。编码是将字符串转换为字节数据(bytes),而解码是将字节数据转换为字符串。常见的应用场景包括文件读取、网络通信、加密处理等。
编码:encode()
字符串通过指定编码格式转为字节类型。常见的编码格式有 UTF-8、ASCII、GBK 等。
# 使用 UTF-8 编码字符串为字节
text = "Hello, World!"
encoded_text = text.encode('utf-8')
print(encoded_text) # 输出: b'Hello, World!',这是字节类型(bytes)
# 使用 GBK 编码(常用于中文字符)
text = "你好"
encoded_text = text.encode('gbk')
print(encoded_text) # 输出: b'\xc4\xe3\xba\xc3'
解码:decode()
字节数据可以通过指定编码格式解码回字符串。
# 字节数据解码为字符串
encoded_text = b'Hello, World!'
decoded_text = encoded_text.decode('utf-8')
print(decoded_text) # 输出: Hello, World!
# 解码 GBK 编码的字节数据
encoded_text = b'\xc4\xe3\xba\xc3'
decoded_text = encoded_text.decode('gbk')
print(decoded_text) # 输出: 你好
错误处理
在编码或解码过程中,如果遇到无法处理的字符,Python 提供了错误处理选项。常见的错误处理模式有:
ignore:忽略无法编码/解码的字符。replace:用替代字符(如?)替代无法编码/解码的字符。strict(默认):如果无法编码/解码,则抛出UnicodeEncodeError或UnicodeDecodeError。
# 编码时使用 ignore 选项
text = "你好"
encoded_text = text.encode('ascii', 'ignore') # 忽略非 ASCII 字符
print(encoded_text) # 输出: b''(空字节)
# 解码时使用 replace 选项
encoded_text = b'Hello, \xe4\xbd\xa0\xe5\xa5\xbd'
decoded_text = encoded_text.decode('utf-8', 'replace')
print(decoded_text) # 输出: Hello, 你?好
常见编码格式
- UTF-8:兼容性好,支持世界上几乎所有的字符集,广泛应用于网页、API 和文件编码。
- ASCII:仅支持英语字符。
- GBK/GB2312:常见于中文环境中,GBK 是对 GB2312 的扩展。
Python 2 与 Python 3 的区别
- 在 Python 2 中,字符串默认是字节类型(
str),而在 Python 3 中,字符串默认是 Unicode 类型(str),字节数据使用bytes类型。 - Python 2 使用
unicode类型处理 Unicode 字符串,需要显式地调用encode()和decode(),而 Python 3 的字符串默认为 Unicode,字节数据必须显式转换为bytes。
好的,以下是按照分类整理并附带代码示例的 Python 3.8 字符串方法:
大小写和字符转换
-
capitalize(): 将字符串的第一个字符转换为大写,其余字符转换为小写。text = 'hello' print(text.capitalize()) # 输出 'Hello' -
casefold(): 返回一个新的字符串,所有字符都转换为小写,适用于语言无关的比较。text = 'HELLO' print(text.casefold()) # 输出 'hello' -
lower(): 返回一个新的字符串,将所有字符转换为小写。text = 'HELLO' print(text.lower()) # 输出 'hello' -
upper(): 返回一个新的字符串,将所有字符转换为大写。text = 'hello' print(text.upper()) # 输出 'HELLO' -
swapcase(): 返回一个新的字符串,将所有大写字母转换为小写字母,反之亦然。text = 'HeLLo' print(text.swapcase()) # 输出 'hElLO'
字符串对齐
-
center(width, fillchar=' '): 返回一个新的字符串,将原字符串居中,填充指定的字符,默认使用空格。text = 'hello' print(text.center(10, '-')) # 输出 '--hello---' -
ljust(width, fillchar=' '): 返回一个新的字符串,将原字符串左对齐,剩余部分填充指定的字符。text = 'hello' print(text.ljust(10, '-')) # 输出 'hello-----' -
rjust(width, fillchar=' '): 返回一个新的字符串,将原字符串右对齐,剩余部分填充指定的字符。text = 'hello' print(text.rjust(10, '-')) # 输出 '-----hello' -
zfill(width): 返回一个新的字符串,将原字符串填充为指定宽度,前面补零。text = '42' print(text.zfill(5)) # 输出 '00042' -
expandtabs(tabsize=8): 返回一个新的字符串,将字符串中的制表符(\t)替换为指定数量的空格。text = 'hello\tworld' print(text.expandtabs(4)) # 输出 'hello world'
查找与定位
-
find(substring, start=0, end=len(string)): 返回子字符串第一次出现的索引,如果找不到返回 -1。text = 'hello' print(text.find('l')) # 输出 2 -
index(substring, start=0, end=len(string)): 类似于find(),但如果子字符串不存在,则会抛出ValueError。text = 'hello' print(text.index('l')) # 输出 2 -
rfind(substring, start=0, end=len(string)): 返回子字符串最后一次出现的索引,找不到返回 -1。text = 'hello' print(text.rfind('l')) # 输出 3 -
rindex(substring, start=0, end=len(string)): 类似于rfind(),但找不到时抛出ValueError。text = 'hello' print(text.rindex('l')) # 输出 3 -
startswith(prefix, start=0, end=len(string)): 判断字符串是否以指定前缀开始。text = 'hello' print(text.startswith('h')) # 输出 True -
endswith(suffix, start=0, end=len(string)): 判断字符串是否以指定后缀结束。text = 'hello' print(text.endswith('o')) # 输出 True
字符串分割与连接
-
split(separator=None, maxsplit=-1): 将字符串分割成多个部分,返回一个列表。text = 'hello world' print(text.split()) # 输出 ['hello', 'world'] -
splitlines(keepends=False): 按行分割字符串,返回一个列表。text = 'hello\nworld' print(text.splitlines()) # 输出 ['hello', 'world'] -
join(iterable): 将一个可迭代对象中的元素连接为一个字符串。text = '-' print(text.join(['a', 'b', 'c'])) # 输出 'a-b-c' -
partition(separator): 将字符串分成三个部分:分隔符之前、分隔符、分隔符之后。text = 'hello world' print(text.partition(' ')) # 输出 ('hello', ' ', 'world')
去除空白字符
-
strip(chars=None): 返回一个新的字符串,去除字符串两端的空白或指定字符。text = ' hello ' print(text.strip()) # 输出 'hello' -
lstrip(chars=None): 返回一个新的字符串,去除字符串左侧的空白或指定字符。text = ' hello ' print(text.lstrip()) # 输出 'hello ' -
rstrip(chars=None): 返回一个新的字符串,去除字符串右侧的空白或指定字符。text = ' hello ' print(text.rstrip()) # 输出 ' hello'
字符串替换
-
replace(old, new, count=-1): 替换字符串中的指定子字符串。text = 'hello' print(text.replace('e', 'a')) # 输出 'hallo' -
translate(table): 根据字符映射表对字符串进行转换。table = str.maketrans('h', 'j') text = 'hello' print(text.translate(table)) # 输出 'jello' -
maketrans(x, y): 返回一个字符映射表,可以用于translate()方法。table = str.maketrans('abc', '123') text = 'abc' print(text.translate(table)) # 输出 '123'
字符串检查与判断
-
isalnum(): 如果字符串只包含字母和数字,返回True。text = 'hello123' print(text.isalnum()) # 输出 True -
isalpha(): 如果字符串只包含字母,返回True。text = 'hello' print(text.isalpha()) # 输出 True -
isascii(): 如果字符串中的所有字符都是 ASCII 字符,返回True。text = 'hello' print(text.isascii()) # 输出 True -
isdecimal(): 如果字符串只包含十进制字符,返回True。text = '12345' print(text.isdecimal()) # 输出 True -
isdigit(): 如果字符串只包含数字字符,返回True。text = '12345' print(text.isdigit()) # 输出 True -
isidentifier(): 如果字符串是一个合法的标识符,返回True。text = 'hello' print(text.isidentifier()) # 输出 True -
islower(): 如果字符串中的所有字母都是小写字母,返回True。text = 'hello' print(text.islower()) # 输出 True -
isnumeric(): 如果字符串只包含数字字符,返回True。text = '12345' print(text.isnumeric()) # 输出 True -
isprintable(): 如果字符串中的所有字符都是可打印的,返回True。text = 'hello' print(text.isprintable()) # 输出 True -
isupper(): 如果字符串中的所有字母都是大写字母,返回True。text = 'HELLO' print(text.isupper()) # 输出 True
5. 字节
在 Python 中,字节类型(bytes)用于表示二进制数据。字节类型是不可变的,而可变字节类型(bytearray)是可变的。
创建
# 使用字节字面量
b = b'hello'
# 使用 bytes() 函数
b = bytes("hello", "utf-8")
# 使用 bytearray() 函数
ba = bytearray("hello", "utf-8")
访问
b = b'hello'
print(b[0]) # 输出: 104
print(b[1:3]) # 输出: b'el'
修改(仅适用于 bytearray)
ba = bytearray(b'hello')
ba[0] = 72 # 修改第一个字节
print(ba) # 输出: bytearray(b'Hello')
常见方法
decode():将字节数据解码为字符串。
b = b'hello'
s = b.decode("utf-8")
print(s) # 输出: hello
hex():将字节数据转换为十六进制字符串。
b = b'hello'
print(b.hex()) # 输出: 68656c6c6f
6. 列表
创建
Python 中创建列表有多种方式,下面是一些常见的用法:
空列表
empty_list = []
empty_list = list()
字面量初始化创建
fruits = ["apple", "banana", "cherry"]
从其他可迭代对象转换
numbers = list(range(5)) # [0, 1, 2, 3, 4]
tuple_data = (1, 2, 3)
list_from_tuple = list(tuple_data) # [1, 2, 3]
string_data = "hello"
list_from_string = list(string_data) # ['h', 'e', 'l', 'l', 'o']
使用列表推导式创建列表
squares = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
添加
append()
将一个元素添加到列表的末尾。
fruits = ["apple", "banana"]
fruits.append("cherry") # ['apple', 'banana', 'cherry']
extend()
将另一个可迭代对象的所有元素添加到列表的末尾。
fruits = ["apple", "banana"]
fruits.extend(["cherry", "date"]) # ['apple', 'banana', 'cherry', 'date']
insert()
将一个元素插入到指定的索引位置。如果索引超出范围,元素将被添加到末尾。
fruits = ["apple", "banana"]
fruits.insert(1, "cherry") # ['apple', 'cherry', 'banana']
+ 运算符
将一个列表的所有元素添加到另一个列表中,生成一个新的列表。
list1 = [1, 2]
list2 = [3, 4]
merged_list = list1 + list2 # [1, 2, 3, 4]
* 运算符
将列表的内容重复指定次数。
numbers = [1, 2]
repeated_list = numbers * 3 # [1, 2, 1, 2, 1, 2]
+= 运算符
将另一个可迭代对象中的元素添加到现有列表的末尾。
fruits = ["apple", "banana"]
fruits += ["cherry", "date"] # ['apple', 'banana', 'cherry', 'date']
列表推导式
根据条件添加多个元素。
numbers = [x for x in range(5)] # [0, 1, 2, 3, 4]
numbers = [x for x in range(5) if x > 2] # [3, 4]
使用 append() 添加多个元素
可以将一个列表作为单个元素添加进列表(这会生成嵌套的列表)。
fruits = ["apple", "banana"]
fruits.append(["cherry", "date"]) # ['apple', 'banana', ['cherry', 'date']]
删除
remove()
删除列表中第一次出现的指定元素。如果元素不存在,抛出 ValueError 异常。
fruits = ["apple", "banana", "cherry"]
fruits.remove("banana") # ['apple', 'cherry']
pop()
根据索引删除并返回该位置的元素。若不指定索引,则默认删除并返回最后一个元素。
fruits = ["apple", "banana", "cherry"]
removed_item = fruits.pop(1) # 删除索引为 1 的元素,返回 'banana'
print(fruits) # ['apple', 'cherry']
# 如果不传递索引,则默认删除最后一个元素
last_item = fruits.pop() # 返回 'cherry'
print(fruits) # ['apple']
del 关键字
根据索引删除指定元素,或者删除切片中的一部分。del 不返回删除的元素。
fruits = ["apple", "banana", "cherry"]
del fruits[1] # 删除索引为 1 的元素
print(fruits) # ['apple', 'cherry']
# 删除整个列表
del fruits # 完全删除列表
# 删除切片
fruits = ["apple", "banana", "cherry", "date"]
del fruits[1:3] # 删除索引 1 到 2 的元素
print(fruits) # ['apple', 'date']
clear()
删除列表中的所有元素。
fruits = ["apple", "banana", "cherry"]
fruits.clear() # []
列表推导式
列表推导式可以根据条件生成新列表,删除不符合条件的元素。
fruits = ["apple", "banana", "cherry", "date"]
fruits = [fruit for fruit in fruits if fruit != "banana"] # 删除 "banana"
print(fruits) # ['apple', 'cherry', 'date']
filter()
可以根据条件过滤元素,返回一个新的迭代器。
fruits = ["apple", "banana", "cherry", "date"]
fruits = list(filter(lambda x: x != "banana", fruits)) # 删除 "banana"
print(fruits) # ['apple', 'cherry', 'date']
获取
索引
索引用于访问列表中的单个元素。Python 中的列表索引是基于 0 的,也就是说,第一个元素的索引为 0,第二个为 1,以此类推。
允许使用负数索引,负数索引表示从列表的末尾开始计数,-1 表示最后一个元素,-2 表示倒数第二个元素,依此类推。
# 正向索引
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[0]) # 'apple' - 第一个元素
print(fruits[1]) # 'banana' - 第二个元素
# 负向索引
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[-1]) # 'date' - 最后一个元素
切片
切片用于访问列表中的一部分元素,可以通过指定起始索引和结束索引来提取列表的子集。切片返回一个新的列表。
基本切片语法:
list[start:end:step]
start:切片的起始索引(包含)。end:切片的结束索引(不包含)。step:步长,默认为 1。步长大于 1 时,表示每隔若干个元素取一个。
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
# 从索引 1 到 3(不包括 3),即 'banana', 'cherry'
print(fruits[1:3]) # ['banana', 'cherry']
# 从索引 2 到列表结束,取 'cherry', 'date', 'elderberry'
print(fruits[2:]) # ['cherry', 'date', 'elderberry']
# 从列表开头到索引 3(不包括 3),取 'apple', 'banana', 'cherry'
print(fruits[:3]) # ['apple', 'banana', 'cherry']
# 从索引 1 到 4,步长为 2,取 'banana' 和 'date'
print(fruits[1:4:2]) # ['banana', 'date']
# 复制整个列表(不指定任何参数)
print(fruits[:]) # ['apple', 'banana', 'cherry', 'date', 'elderberry']
# 使用负数索引进行切片,从倒数第三个元素到倒数第一个元素,取 'cherry', 'date'
print(fruits[-3:]) # ['cherry', 'date', 'elderberry']
切片的特殊情况
当 start 或 end 超出列表的范围时,Python 会自动调整:
-
如果
start大于列表长度,则返回空列表。 -
如果
end超出列表长度,则返回列表的剩余部分。fruits = ["apple", "banana", "cherry"] # start 超过列表长度 print(fruits[5:]) # [] - 超过范围,返回空列表 # end 超过列表长度 print(fruits[1:5]) # ['banana', 'cherry'] - 返回到列表末尾 -
步长为负数的情况: 当步长为负数时,切片将从列表的右侧开始读取,
start必须大于end,否则返回空列表。fruits = ["apple", "banana", "cherry", "date", "elderberry"] # 从右侧开始,每次步长为 -1,倒序取元素 print(fruits[::-1]) # ['elderberry', 'date', 'cherry', 'banana', 'apple'] # 从倒数第三个元素到倒数第一个元素,步长为 -1 print(fruits[-3:-1]) # ['cherry', 'date'] # 从倒数第一个元素到倒数第四个元素,步长为 -2 print(fruits[-1:-4:-2]) # ['elderberry', 'cherry']
修改
通过获取到的索引或切片直接通过 = 赋值即可。
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
fruits[0] = ["pear"] # 替换索引元素
fruits[2:3] = ["orange", "pear"] # 替换切片元素
其他
查找元素
index():返回指定元素在列表中的第一个索引位置。如果元素不存在,抛出ValueError异常。
fruits = ["apple", "banana", "cherry"]
print(fruits.index("banana")) # 输出: 1
# 如果元素不存在,抛出异常
# print(fruits.index("pear")) # ValueError: 'pear' is not in list
in:检查某个元素是否在列表中,返回布尔值。
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # True
print("pear" in fruits) # False
长度数量
len():返回列表中元素的个数。
fruits = ["apple", "banana", "cherry"]
print(len(fruits)) # 输出: 3
count():返回某个元素在列表中出现的次数。
fruits = ["apple", "banana", "cherry", "banana"]
print(fruits.count("banana")) # 输出: 2
print(fruits.count("apple")) # 输出: 1
排序反转
sort():对列表进行原地排序,默认按升序排列。对于字符串,按照字母顺序排序。排序是就地修改列表。
numbers = [4, 1, 3, 2]
numbers.sort() # 升序排列
print(numbers) # 输出: [1, 2, 3, 4]
# 降序排列
numbers.sort(reverse=True)
print(numbers) # 输出: [4, 3, 2, 1]
sorted():返回一个新的已排序列表,而不修改原列表。
numbers = [4, 1, 3, 2]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # 输出: [1, 2, 3, 4]
print(numbers) # 原列表不变: [4, 1, 3, 2]
reverse():就地反转列表的元素。
复制编辑
fruits = ["apple", "banana", "cherry"]
fruits.reverse() # 反转列表
print(fruits) # 输出: ['cherry', 'banana', 'apple']
reversed():返回一个反转后的迭代器,可以用于创建反转后的新列表。
fruits = ["apple", "banana", "cherry"]
reversed_fruits = list(reversed(fruits)) # 返回一个新的反转列表
print(reversed_fruits) # 输出: ['cherry', 'banana', 'apple']
拷贝
在 Python 中,列表拷贝指的是创建一个新的列表,其元素与原始列表相同,但在内存中是不同的对象。拷贝的方式有很多种,下面我会介绍几种常用的方式,并说明它们的区别。
1. copy()
copy() 方法创建一个浅拷贝(shallow copy),它会创建一个新的列表,但如果列表中包含可变对象(如子列表、字典等),这些可变对象的引用会被复制,而不是创建新的副本。
fruits = ["apple", "banana", "cherry"]
fruits_copy = fruits.copy()
print(fruits_copy) # 输出: ['apple', 'banana', 'cherry']
2. 使用切片操作 [:]
- 切片操作
[:]也能创建一个浅拷贝,效果与copy()方法相同。 - 使用切片的方式是将整个列表截取出来,实际上会返回一个新的列表对象。
fruits = ["apple", "banana", "cherry"]
fruits_copy = fruits[:]
print(fruits_copy) # 输出: ['apple', 'banana', 'cherry']
3. 使用 list() 构造函数
list() 函数可以将任何可迭代对象(如元组、集合、字符串等)转换为列表,使用该函数可以创建列表的浅拷贝。
fruits = ["apple", "banana", "cherry"]
fruits_copy = list(fruits)
print(fruits_copy) # 输出: ['apple', 'banana', 'cherry']
4. 使用 copy 模块的 copy() 函数
copy 模块提供了一个 copy() 函数,可以用于创建浅拷贝。它与 list.copy() 方法或切片操作 [:] 类似。
import copy
fruits = ["apple", "banana", "cherry"]
fruits_copy = copy.copy(fruits)
print(fruits_copy) # 输出: ['apple', 'banana', 'cherry']
5. 深拷贝(Deep Copy)
如果列表中包含其他可变对象(如子列表、字典等),使用浅拷贝(如 copy() 或 [:])会复制对象的引用,而不是创建新对象。这会导致修改其中一个列表时,另一个列表的相关部分也被修改。
如果需要完全独立的列表(包括嵌套对象),可以使用深拷贝(deep copy)。Python 的 copy 模块提供了 deepcopy() 函数,可以创建深拷贝。
import copy
# 列表包含子列表
fruits = ["apple", ["banana", "cherry"], "date"]
fruits_copy = copy.deepcopy(fruits)
# 修改原始列表中的子列表元素
fruits[1][0] = "blueberry"
print(fruits) # 输出: ['apple', ['blueberry', 'cherry'], 'date']
print(fruits_copy) # 输出: ['apple', ['banana', 'cherry'], 'date']
区别
- 浅拷贝(
copy()、切片[:]、list()、copy.copy())会创建一个新的列表,但如果列表中有其他可变对象(如子列表、字典等),它们会被共享,即修改其中一个列表中的可变对象会影响到另一个列表。 - 深拷贝(
copy.deepcopy())会递归地创建所有元素的副本,包括嵌套的可变对象,确保两个列表完全独立。
import copy
# 浅拷贝示例
original = [1, [2, 3]]
shallow_copy = copy.copy(original)
# 修改原始列表中的子列表
original[1][0] = 99
print(original) # 输出: [1, [99, 3]]
print(shallow_copy) # 输出: [1, [99, 3]] # 浅拷贝也受影响
# 深拷贝示例
deep_copy = copy.deepcopy(original)
# 修改原始列表中的子列表
original[1][0] = 100
print(original) # 输出: [1, [100, 3]]
print(deep_copy) # 输出: [1, [99, 3]] # 深拷贝不受影响
7. 元组
创建
Python 中创建元组有多种方式,下面是一些常见的用法:
空元组
empty_tuple = ()
empty_tuple = tuple()
字面量初始化创建
fruits = ("apple", "banana", "cherry")
从其他可迭代对象转换
numbers = tuple(range(5)) # (0, 1, 2, 3, 4)
list_data = [1, 2, 3]
tuple_from_list = tuple(list_data) # (1, 2, 3)
string_data = "hello"
tuple_from_string = tuple(string_data) # ('h', 'e', 'l', 'l', 'o')
单元素元组
single_element_tuple = ("apple",) # 注意逗号
访问
索引
索引用于访问元组中的单个元素。Python 中的元组索引是基于 0 的,也就是说,第一个元素的索引为 0,第二个为 1,以此类推。
允许使用负数索引,负数索引表示从元组的末尾开始计数,-1 表示最后一个元素,-2 表示倒数第二个元素,依此类推。
# 正向索引
fruits = ("apple", "banana", "cherry", "date")
print(fruits[0]) # 'apple' - 第一个元素
print(fruits[1]) # 'banana' - 第二个元素
# 负向索引
fruits = ("apple", "banana", "cherry", "date")
print(fruits[-1]) # 'date' - 最后一个元素
切片
切片用于访问元组中的一部分元素,可以通过指定起始索引和结束索引来提取元组的子集。切片返回一个新的元组。
基本切片语法:
tuple[start:end:step]
start:切片的起始索引(包含)。end:切片的结束索引(不包含)。step:步长,默认为 1。步长大于 1 时,表示每隔若干个元素取一个。
fruits = ("apple", "banana", "cherry", "date", "elderberry")
# 从索引 1 到 3(不包括 3),即 'banana', 'cherry'
print(fruits[1:3]) # ('banana', 'cherry')
# 从索引 2 到元组结束,取 'cherry', 'date', 'elderberry'
print(fruits[2:]) # ('cherry', 'date', 'elderberry')
# 从元组开头到索引 3(不包括 3),取 'apple', 'banana', 'cherry'
print(fruits[:3]) # ('apple', 'banana', 'cherry')
# 从索引 1 到 4,步长为 2,取 'banana' 和 'date'
print(fruits[1:4:2]) # ('banana', 'date')
# 复制整个元组(不指定任何参数)
print(fruits[:]) # ('apple', 'banana', 'cherry', 'date', 'elderberry')
# 使用负数索引进行切片,从倒数第三个元素到倒数第一个元素,取 'cherry', 'date'
print(fruits[-3:]) # ('cherry', 'date', 'elderberry')
切片的特殊情况
当 start 或 end 超出元组的范围时,Python 会自动调整:
-
如果
start大于元组长度,则返回空元组。 -
如果
end超出元组长度,则返回元组的剩余部分。fruits = ("apple", "banana", "cherry") # start 超过元组长度 print(fruits[5:]) # () - 超过范围,返回空元组 # end 超过元组长度 print(fruits[1:5]) # ('banana', 'cherry') - 返回到元组末尾 -
步长为负数的情况: 当步长为负数时,切片将从元组的右侧开始读取,
start必须大于end,否则返回空元组。fruits = ("apple", "banana", "cherry", "date", "elderberry") # 从右侧开始,每次步长为 -1,倒序取元素 print(fruits[::-1]) # ('elderberry', 'date', 'cherry', 'banana', 'apple') # 从倒数第三个元素到倒数第一个元素,步长为 -1 print(fruits[-3:-1]) # ('cherry', 'date') # 从倒数第一个元素到倒数第四个元素,步长为 -2 print(fruits[-1:-4:-2]) # ('elderberry', 'cherry')
其他
查找元素
index():返回指定元素在元组中的第一个索引位置。如果元素不存在,抛出ValueError异常。
fruits = ("apple", "banana", "cherry")
print(fruits.index("banana")) # 输出: 1
# 如果元素不存在,抛出异常
# print(fruits.index("pear")) # ValueError: 'pear' is not in tuple
in:检查某个元素是否在元组中,返回布尔值。
fruits = ("apple", "banana", "cherry")
print("banana" in fruits) # True
print("pear" in fruits) # False
长度数量
len():返回元组中元素的个数。
fruits = ("apple", "banana", "cherry")
print(len(fruits)) # 输出: 3
count():返回某个元素在元组中出现的次数。
fruits = ("apple", "banana", "cherry", "banana")
print(fruits.count("banana")) # 输出: 2
print(fruits.count("apple")) # 输出: 1
连接与重复
+运算符:将两个元组连接起来,生成一个新的元组。
tuple1 = (1, 2)
tuple2 = (3, 4)
merged_tuple = tuple1 + tuple2 # (1, 2, 3, 4)
*运算符:将元组的内容重复指定次数。
numbers = (1, 2)
repeated_tuple = numbers * 3 # (1, 2, 1, 2, 1, 2)
不可变性
元组是不可变的,这意味着一旦创建,就不能修改其内容。如果需要修改元组,可以将其转换为列表,进行修改后再转换回元组。
fruits = ("apple", "banana", "cherry")
fruits_list = list(fruits)
fruits_list[0] = "pear"
fruits = tuple(fruits_list)
print(fruits) # ('pear', 'banana', 'cherry')
解包
元组解包允许将元组中的元素直接赋值给多个变量。
fruits = ("apple", "banana", "cherry")
a, b, c = fruits
print(a) # 'apple'
print(b) # 'banana'
print(c) # 'cherry'
嵌套元组
元组可以包含其他元组,形成嵌套结构。
nested_tuple = (1, (2, 3), (4, (5, 6)))
print(nested_tuple[1]) # (2, 3)
print(nested_tuple[2][1]) # (5, 6)
元组与列表的区别
- 元组是不可变的,而列表是可变的。
- 元组使用小括号
(),列表使用方括号[]。 - 元组通常用于存储异构数据(不同类型的数据),而列表通常用于存储同构数据(相同类型的数据)。
# 元组
person = ("Alice", 30, "Engineer")
# 列表
numbers = [1, 2, 3, 4, 5]
8. 字典
创建
Python 中创建字典有多种方式,下面是一些常见的用法:
空字典
empty_dict = {}
empty_dict = dict()
字面量初始化创建
person = {"name": "Alice", "age": 30, "job": "Engineer"}
使用 dict() 构造函数
person = dict(name="Alice", age=30, job="Engineer")
从键值对序列创建
pairs = [("name", "Alice"), ("age", 30), ("job", "Engineer")]
person = dict(pairs)
访问
通过键访问值
person = {"name": "Alice", "age": 30, "job": "Engineer"}
print(person["name"]) # 输出: Alice
使用 get() 方法
person = {"name": "Alice", "age": 30, "job": "Engineer"}
print(person.get("name")) # 输出: Alice
print(person.get("salary", "Not specified")) # 输出: Not specified
修改
添加或更新键值对
person = {"name": "Alice", "age": 30}
person["job"] = "Engineer" # 添加新键值对
person["age"] = 31 # 更新已有键值对
使用 update() 方法
person = {"name": "Alice", "age": 30}
person.update({"age": 31, "job": "Engineer"})
删除
使用 del 关键字
person = {"name": "Alice", "age": 30, "job": "Engineer"}
del person["age"]
使用 pop() 方法
person = {"name": "Alice", "age": 30, "job": "Engineer"}
age = person.pop("age")
使用 popitem() 方法
person = {"name": "Alice", "age": 30, "job": "Engineer"}
item = person.popitem() # 随机删除一个键值对
使用 clear() 方法
person = {"name": "Alice", "age": 30, "job": "Engineer"}
person.clear()
其他
查找键值对
keys():返回字典中所有键的视图。
person = {"name": "Alice", "age": 30, "job": "Engineer"}
print(person.keys()) # 输出: dict_keys(['name', 'age', 'job'])
values():返回字典中所有值的视图。
person = {"name": "Alice", "age": 30, "job": "Engineer"}
print(person.values()) # 输出: dict_values(['Alice', 30, 'Engineer'])
items():返回字典中所有键值对的视图。
person = {"name": "Alice", "age": 30, "job": "Engineer"}
print(person.items()) # 输出: dict_items([('name', 'Alice'), ('age', 30), ('job', 'Engineer')])
长度
len():返回字典中键值对的数量。
person = {"name": "Alice", "age": 30, "job": "Engineer"}
print(len(person)) # 输出: 3
字典合并
update():将一个字典的键值对更新到另一个字典中。
person = {"name": "Alice", "age": 30}
additional_info = {"job": "Engineer", "city": "New York"}
person.update(additional_info)
字典解包:使用**操作符合并字典。
person = {"name": "Alice", "age": 30}
additional_info = {"job": "Engineer", "city": "New York"}
merged_dict = {**person, **additional_info}
8. 集合
创建
Python 中创建集合有多种方式,下面是一些常见的用法:
空集合
empty_set = set()
字面量初始化创建
fruits = {"apple", "banana", "cherry"}
从其他可迭代对象转换
numbers = set(range(5)) # {0, 1, 2, 3, 4}
list_data = [1, 2, 3]
set_from_list = set(list_data) # {1, 2, 3}
string_data = "hello"
set_from_string = set(string_data) # {'h', 'e', 'l', 'o'}
添加
add()
将一个元素添加到集合中。
fruits = {"apple", "banana"}
fruits.add("cherry")
update()
将另一个可迭代对象的所有元素添加到集合中。
fruits = {"apple", "banana"}
fruits.update(["cherry", "date"])
删除
remove()
删除集合中的指定元素。如果元素不存在,抛出 KeyError 异常。
fruits = {"apple", "banana", "cherry"}
fruits.remove("banana")
discard()
删除集合中的指定元素。如果元素不存在,不会抛出异常。
fruits = {"apple", "banana", "cherry"}
fruits.discard("banana")
pop()
随机删除并返回集合中的一个元素。
fruits = {"apple", "banana", "cherry"}
removed_item = fruits.pop()
clear()
删除集合中的所有元素。
fruits = {"apple", "banana", "cherry"}
fruits.clear()
集合运算
并集
union():返回两个集合的并集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union_set = set1.union(set2) # {1, 2, 3, 4, 5}
|运算符:返回两个集合的并集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union_set = set1 | set2 # {1, 2, 3, 4, 5}
交集
intersection():返回两个集合的交集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
intersection_set = set1.intersection(set2) # {3}
&运算符:返回两个集合的交集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
intersection_set = set1 & set2 # {3}
差集
difference():返回两个集合的差集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
difference_set = set1.difference(set2) # {1, 2}
-运算符:返回两个集合的差集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
difference_set = set1 - set2 # {1, 2}
对称差集
symmetric_difference():返回两个集合的对称差集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
symmetric_difference_set = set1.symmetric_difference(set2) # {1, 2, 4, 5}
^运算符:返回两个集合的对称差集。
set1 = {1, 2, 3}
set2 = {3, 4, 5}
symmetric_difference_set = set1 ^ set2 # {1, 2, 4, 5}
其他
查找元素
in:检查某个元素是否在集合中,返回布尔值。
fruits = {"apple", "banana", "cherry"}
print("banana" in fruits) # True
print("pear" in fruits) # False
长度
len():返回集合中元素的数量。
fruits = {"apple", "banana", "cherry"}
print(len(fruits)) # 输出: 3
集合比较
issubset():检查一个集合是否是另一个集合的子集。
set1 = {1, 2, 3}
set2 = {1, 2}
print(set2.issubset(set1)) # True
issuperset():检查一个集合是否是另一个集合的超集。
set1 = {1, 2, 3}
set2 = {1, 2}
print(set1.issuperset(set2)) # True
isdisjoint():检查两个集合是否没有交集。
set1 = {1, 2, 3}
set2 = {4, 5, 6}
print(set1.isdisjoint(set2)) # True
9. 总结
对比
| 数据类型 | 描述 | 可变性 | 有序性 |
|---|---|---|---|
None | 表示空值或无值 | 不可变 | / |
bool | 布尔类型,表示真或假 | 不可变 | / |
int | 整数类型 | 不可变 | / |
float | 浮点数类型 | 不可变 | / |
complex | 复数类型 | 不可变 | / |
str | 字符串类型 | 不可变 | / |
list | 列表类型,可变序列 | 可变 | 有序 |
tuple | 元组类型,不可变序列 | 不可变 | / |
dict | 字典类型,键值对集合 | 可变 | 有序(Python 3.7+) |
set | 集合类型,无序不重复元素 | 可变 | 无序 |
bytes | 字节类型 | 不可变 | 有序 |
bytearray | 可变字节类型 | 可变 | 有序 |
转换
| 函数 | 描述 | 示例 |
|---|---|---|
int(x) | 将 x 转换为整数 | int("42") -> 42 |
float(x) | 将 x 转换为浮点数 | float("3.14") -> 3.14 |
complex(x) | 将 x 转换为复数 | complex(1, 2) -> (1+2j) |
str(x) | 将 x 转换为字符串 | str(42) -> "42" |
list(x) | 将 x 转换为列表 | list((1, 2, 3)) -> [1, 2, 3] |
tuple(x) | 将 x 转换为元组 | tuple([1, 2, 3]) -> (1, 2, 3) |
dict(x) | 将 x 转换为字典 | dict([("key", "value")]) -> {"key": "value"} |
set(x) | 将 x 转换为集合 | set([1, 2, 3]) -> {1, 2, 3} |
bool(x) | 将 x 转换为布尔值 | bool(1) -> True |
bytes(x) | 将 x 转换为字节 | bytes("hello", "utf-8") -> b'hello' |
bytearray(x) | 将 x 转换为可变字节 | bytearray("hello", "utf-8") -> bytearray(b'hello') |