1.4.2 元组类型
tuple
元组用来存储有序数据,多个值用逗号隔开。
-
元组使用小括号 ( ),虽然圆括号可有可无;
-
元组的元素多为异质的,不可变的(immutable),通过解包或索引访问;
-
列表的元素多为同质的,可变的(mutable),可迭代访问;
1.4.2.1 元组创建
-
创建元组的字面值
用小括号() 括起来,单个元素括起来后加逗号来区分单个元素还是元组
t = () # 空元组 t = (100,) # 一个元素的元组, t = 100, # 一个元素的元组,在元素后面添加逗号,否则括号会被当作运算符 t = (1, 2, 3) # 含有三个数据元素的元组 t = ( 'hqyj', 2004) # 存放不同类型的元组 t = 1, 2, 3 # 含有三个数据元素的元组
-
创建元组的函数 tuple
t = tuple() # t = () t = tuple(range(5)) # t = (0, 1, 2, 3, 4)
1.4.2.2 元组操作
元组是不可变容器,相对来讲操作少一些。
1.4.2.2.1 删除元组
元组中的元素值是不允许删除的,但可以用del删除元组
tup = ('openAI', 'hqyj', 100, 200) print (tup) del tup print (tup) #name 'tup' is not defined
1.4.2.2.2 查看元组
元组的元素访问可以像列表一样通过下标、切割等方式去访问。。
tup1 = ('python', 'hqyj', 100, 200) tup2 = (1, 2, 3, 4, 5, 6, 7 ) print (tup1[0])#python print (tup2[1:5])#(2, 3, 4, 5) print (tup2[:4])#(1, 2, 3, 4) print (tup2[2:])#(3, 4, 5, 6, 7)
1.4.2.2.3 解包技能
必备技能
序列解包:解构赋值,左侧变量与右侧序列元素的数量应相等
fruit = ('apple', 'pear', 'peach') f1, f2, f3 = fruit print(f1, f2, f3)
等价于:
f1 = fruit[0] # 'apple' f2 = fruit[1] # 'pear' f3 = fruit[2] # 'peach'
1.4.2.3 元组运算
元组中的元素值是不允许修改的,但可以对元组进行连接组合
tup1 = (12, 34.56) tup2 = ('abc', 'xyz') # 创建一个新的元组 tup3 = tup1 + tup2 print (tup3) t = (1, 2, 3) + (4, 5, 6) t += (7, 8, 9) # 等同于 t = t + (7, 8, 9) t = t * 2 t *= 2 5 in t
1.4.2.4 元组不可变
不可变指的是变量指向的内存中的内容不可变,但是变量的指向是可以改变的。
tup = (1, 2, 3, 4, 5, 6, 7) tup[1] = 100 print(tup)#报错'tuple' object does not support item assignment
变量是可以重新赋值的
tup1 = (12, 34.56) tup1 = (12, 100) tup1
1.4.2.5 元组常用API
Python元组包含了以下内置函数
序号 | 方法 | 描述 |
---|---|---|
1 | len(tuple) | 返回元组中元素个数。 |
2 | max(tuple) | 返回元组中元素最大值。 |
3 | min(tuple) | 返回元组中元素最小值。 |
4 | tuple(list) | 将列表转换为元组。 |
1.4.3 字典dict
-
字典是可变容器,可存储任意类型对象
-
字典以键(key)-值(value)对的形式进行映射,键值对用冒号分割,对之间用逗号分割
-
d = {key1 : value1, key2 : value2, key3 : value3 }
-
字典的数据是无序的
-
字典的键只能用不可变类型,且不能重复
-
字典的数据用键进行索引,不能用整数进行索引
1.4.3.1 字典创建
-
创建字典的字面值
d = {} # 创建空字典 d = {'name': "weimingze", "age": 35} d = {'a': [1, 2, 3]} d = {'b': {"bb": 222}} d = {1:'壹', 2:'贰', 5:'伍'} d = {(1, 2, 3):'壹贰伍'}
-
以下写法会存在问题
d = {'a': 1, 'b': 2, 'a': 3} # 字典的键不能重复 d = {'a': 3, 'b': 2} d = {[1, 2, 3]: 'a'} # TypeError: unhashable type: 'list'
-
字典的创建函数 dict()
d = dict() # d = {} d = dict([("name", "小王"), ("age", 35)]) # {'name': '小王', 'age': 35} d = dict(a=1, b=2, c=3) # {'a':1, 'b':2, 'c':3} d = dict([1, 2, 3, 4]) # 错
1.4.3.2 字典操作
增、删、改、查
1.4.3.2.1 增加或修改
添加和修改字典的元素
-
语法
字典[键key] = 表达式
键不存在, 就添加
键存在, 会改变键对应的值
-
示例
d = {} d['name'] = 'tarena' # 添加键值对 d['age'] = 18 # d = {'name': 'tarena', 'age': 18} d['age'] = 19 # 改变键对应的值
1.4.3.2.2 访问值
-
字典的键索引
-
语法
字典[键key]
-
示例
d = {'one': 1, 'two': 2} print(d['two'])
-
如果键不存在,会报错
mydic = {'Name': 'hqyj', 'Age': 7, 'Class': 'First'} print (mydic['Alice']) # KeyError: 'Alice'
-
1.4.3.2.3 in/not in
in用于判断一个键是否存在于字典中,存在返回True, 否则返回False
-
示例
d = dict(a=1, b=2) # d = {'a': 1, 'b': 2} print('a' in d) # True print(1 in d) # False print('hello' not in d) # True
1.4.3.2.4 删除元素
能删单一的元素也能清空字典,显式删除一个字典用del命令
-
语法
del 字典[键]
-
示例
mydic = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} del mydic['Name'] # 删除键 'Name' mydic.clear() # 清空字典 print (mydic['Age']) print (mydic['School']) del mydic # 删除字典
1.4.3.3 字典特性
-
不允许同一个键出现两次,否则后一个覆盖前一个
mydic = {'Name': 'jack', 'Age': 27, 'Name': 'karen'} print (mydic['Name'])
-
键必须不可变,可以用数字、字符串或元组,列表不行
mydic1 = {97:"a",98:"b"} mydic2 = {"name":"karen","age":27} mydic3 = {['Name']: 'karen', 'Age': 27} print(mydic3[['Name']]) #报错unhashable type: 'list'
1.4.3.4 常用API
操作字典的函数:
序号 | 函数 | 描述 |
---|---|---|
1 | len(dict) | 计算字典元素个数,即键的总数。 |
2 | str(dict) | 输出字典,可以打印的字符串表示。 |
3 | type(variable) | 返回输入的变量类型,如果变量是字典就返回字典类型。 |
字典的方法:
序号 | 函数及描述 |
---|---|
1 | dict.clear()删除字典内所有元素 |
2 | dict.copy()返回一个字典的浅复制 |
4 | dict.get(key, default=None)返回指定键的值,如果键不在字典中返回 default 设置的默认值 |
5 | key in dict如果键在字典dict里返回true,否则返回false |
6 | dict.items()以列表返回一个视图对象 |
7 | dict.keys()返回一个视图对象 |
9 | dict.update(dict2)把字典dict2的键/值对更新到dict里 |
10 | dict.values()返回一个视图对象 |
11 | pop(key,default)删除字典 key(键)所对应的值,返回被删除的值。 |
示例
original_dict = {'a': 1, 'b': [1, 2, 3]} shallow_copied_dict = original_dict.copy() # 修改原始字典中的可变对象 # 对于可变对象(如列表、字典),修改原始字典中的值会影响浅复制的字典,因为它们引用的是同一个对象 original_dict['b'].append(4) # 对于不可变对象(如整数、字符串、元组),修改原始字典中的值不会影响浅复制的字典。 original_dict['a']=2 print(original_dict) # 输出: {'a': 2, 'b': [1, 2, 3, 4]} print(shallow_copied_dict) # 输出: {'a': 1, 'b': [1, 2, 3, 4]}
# 创建一个新字典,键为列表中的元素,值为None keys = ['a', 'b', 'c'] new_dict = dict.fromkeys(keys) print(new_dict) # 输出: {'a': None, 'b': None, 'c': None} # 创建一个新字典,键为列表中的元素,值为指定的值 value = 0 new_dict = dict.fromkeys(keys, value) print(new_dict) # 输出: {'a': 0, 'b': 0, 'c': 0} # 如果提供的 value 是不可变对象(如整数、字符串、元组等),每个键将有一个独立的值副本 new_dict['a'] = 1 print(new_dict) # 如果提供的值是可变对象(如列表、字典等),那么所有键将共享同一个可变对象。这意味着对这个可变对象的任何修改都会反映在所有键的值上。 keys = ['a', 'b', 'c'] value = [] new_dict = dict.fromkeys(keys, value) print(new_dict) # 输出: {'a': [], 'b': [], 'c': []} # 修改可变对象 new_dict['a'].append('x') print(new_dict) # 输出: {'a': ['x'], 'b': ['x'], 'c': ['x']}
# 返回指定键的值,如果键不在字典中返回 default 设置的默认值 dict = {'a': 1, 'b': 2} print(dict.get('c')) print(dict.get('c', 0))
dict1 = {'a': 1, 'b': 2} dict2 = {'b': 3, 'c': 4} # 使用 dict.update() 更新 dict1 # 如果 dict1 中已经存在 dict2 的键,则 dict1 中的值会被 dict2 中的值覆盖 dict1.update(dict2) print(dict1) # 输出: {'a': 1, 'b': 3, 'c': 4}
1.4.4 set/ frozenset
集合set和固定集合frozenset
set的元素值必须是不可变的,set中可以存储int、str、tuple等不可变类型,但不能存储 list、dict 等可变类型。
-
集合是可变的容器,固定集合是不可变的集合
-
集合相当于只有键没有值的字典,当然你也可以理解为键和值相等
-
集合内的数据都是唯一的,不可变的
1.4.4.1 集合创建
-
创建集合的方式
空集合 set()
非空集合用 {} 括起来,值用逗号分隔开
s = set() # 用函数空集合 s = {1, 2, 3, 4} # 创建非空集合的字面值 s = set(range(5)) # 调用 set(可迭代对象) 来创建集合 s = {0, 1, 2, 3, 4} s = set("ABC") # s = {'B', 'C', 'A'} s = set("ABCCCCCCC") # s = {'B', 'C', 'A'} s = set(['ABC']) # s = {'ABC'} 使用 set()函数从列表创建集合 s = set((4, 5, 6, 7))# 使用 set()函数从元组创建集合
-
创建固定集合frozensets的方式
fs = frozenset() # 空固定集合 fs = frozenset() fs = frozenset([1, 2, 3]) # fs = frozenset({1, 2, 3}) frozenset() 只能接受一个可迭代对象参数
注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
1.4.4.2 集合操作
1.4.4.2.1 添加元素
将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作。
-
s.add( x ) 添加元素到集合。
-
s.update( x ) 添加元素到集合,且参数可以是列表、元组、字典等,x 可以有多个,用逗号分开。
s1 = set((4, 5, 6, 7)) s1.add(100) print(s1) s1.update([200,300]) print(s1)
1.4.4.2.2 删除元素
-
s.remove( x ):将元素 x 从集合 s 中移除,不存在会发生错误。
-
s.discard( x ):将元素 x 从集合 s 中移除,不存在也不会发生错误。
-
s.pop():对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。
s1 = {10, 20, 30} s1.remove(20) print(s1) s1.remove(40)#报错
s1 = {10, 20, 30} s1.discard(20) print(s1) s1.discard(40)
s1 = {10, 20, 30} s1.pop() print(s1) del s1 # 也可以直接删除整个集合
1.4.4.2.3 访问与修改
集合是无序的、不可重复的数据结构,不能通过索引来访问其元素。所以也没有对应的修改功能。
TODO:需要通过遍历或者迭代器去访问。
1.4.4.2.4 in/not in
x in s 判断元素 x 是否在集合 s 中,存在返回 True,不存在返回 False。
s1 = {10, 20, 30} print(20 in s1)
1.4.4.3 常用API
集合的方法
方法 | 描述 |
---|---|
add() | 为集合添加元素 |
clear() | 移除集合中的所有元素 |
copy() | 拷贝一个集合 |
difference() | 返回多个集合的差集 |
difference_update() | 移除集合中的元素,该元素在指定的集合也存在。 |
discard() | 删除集合中指定的元素 |
intersection() | 返回集合的交集 |
intersection_update() | 返回集合的交集。 |
isdisjoint() | 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。 |
issubset() | 判断指定集合是否为该方法参数集合的子集。 |
issuperset() | 判断该方法的参数集合是否为指定集合的子集 |
pop() | 随机移除元素 |
remove() | 移除指定元素 |
symmetric_difference() | 返回两个集合中不重复的元素集合。 |
symmetric_difference_update() | 移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。 |
union() | 返回两个集合的并集 |
update() | 给集合添加元素 |
len() | 计算集合元素个数 |
示例:
# 1.len() s1 = {10, 20, 30} print(len(s1)) #2. clear() s1 = {10, 20, 30} s1.clear() print(s1) #3.union() set1 = {1, 2, 3} set2 = {3, 4, 5} set3 = {5, 6, 7} result = set1.union(set2, set3) print(result)
1.5 可变与不可变
Python中,变量的值分为可变(mutable)或 不可变(immutable),该特征决定了变量在赋值、修改时的行为和性能。
1.5.1 不可变类型
不可变类型的值一旦创建,就无法改变。任何试图修改不可变对象的操作都会创建一个新的对象。常见不可变类型包括:
-
数值类型:int、float、complex
数字的值一旦赋值,不能被修改。
x = 10 print(id(x), hex(id(x))) x = x + 5 # 会创建一个新的整数对象,并将其赋值给 x print(id(x), hex(id(x)))
id():获取变量引用的内存地址;
hex():转换为16进制;
-
字符串
字符串是不可变的,任何试图修改字符串内容的操作都会生成一个新的字符串。
s = "hello" print(id(s)) s = s + " world" # 创建一个新的字符串对象并赋值给 s print(id(s))
-
元组
元组是不可变的容器类型,一旦创建,其内容不能更改。
t = (1, 2, 3) # t[0] = 10 # 会抛出 TypeError: 'tuple' object does not support item assignment
-
冻结集合
frozenset 是不可变版本的集合,一旦创建,无法修改其元素。
fs = frozenset([1, 2, 3]) # fs.add(4) # 会抛出 AttributeError: 'frozenset' object has no attribute 'add'
-
布尔值
布尔值
True
和False
也属于不可变类型。flag = True flag = False # 这不是修改,而是创建了一个新的布尔值并赋值给flag
-
字节串和None
字节串和None为不可变类型。
1.5.2 可变类型
可变类型的值在创建后可以被修改。常见的可变类型:
-
列表
列表是可变的,可以在原地修改其元素、添加或删除元素。
lst = [1, 2, 3] lst[0] = 10 # 修改原列表的元素 lst.append(4) # 添加新的元素
-
字典
字典也是可变类型,可以修改其键值对。
d = {'a': 1, 'b': 2} d['a'] = 10 # 修改字典中键 'a' 对应的值 d['c'] = 3 # 添加新的键值对
-
集合
集合是可变的,可以添加或删除元素。
s = {1, 2, 3} s.add(4) # 添加元素 s.remove(2) # 删除元素
-
自定义对象
自定义类的实例如果没有在类中明确限制其属性,可以修改实例的属性值,因此对象实例也是可变的。
class MyClass: def __init__(self): self.value = 0 obj = MyClass() obj.value = 10 # 修改对象的属性
1.5.3 二者区别
-
内存管理
-
对不可变类型改值时,Python会创建一个新的对象,并将该对象的引用赋给原来的变量。
-
对可变类型修改内容时,不会创建新的对象,而是直接在原地进行修改。
-
-
行为差异
-
不可变对象的引用在修改后总会指向一个新对象,而可变对象的引用在修改时仍然指向原始对象。
-
-
作为字典键
-
不可变类型具有固定的哈希值,可以作为字典的键。
-
可变类型哈希值可能变化,不能作为字典的键。
d = {} d[(1, 2)] = "tuple key" # 元组是不可变的,可以作为字典的键 d[[1, 2]] = "list key" # 会抛出 TypeError: unhashable type: 'list'
-
-
特别注意
以上是基于修改而不是赋值,重新赋值操作都会指向新的对象引用。
1.6 类型判断
使用isinstance判断类型变量
a = 1 print(isinstance(a, int)) #判断是否属于指定类型 str1 = 'abc' print(isinstance(str1, (int, str))) #判断是否属于多个类型之一
1.7 类型转换
这里只是总结一下常见类型转换的函数:
函数 | 说明 | 示例 |
---|---|---|
int(x) | 将 x 转换为整数类型。 | int("10") → 10 |
float(x) | 将 x 转换为浮点数类型。 | float("3.14") → 3.14 |
str(x) | 将 x 转换为字符串类型。 | str(123) → "123" |
list(x) | 将 x 转换为列表类型,x 必须是可迭代对象。 | list((1, 2, 3)) → [1, 2, 3] |
tuple(x) | 将 x 转换为元组类型,x 必须是可迭代对象。 | tuple([1, 2, 3]) → (1, 2, 3) |
set(x) | 将 x 转换为集合类型,x 必须是可迭代对象。 | set([1, 2, 3]) → {1, 2, 3} |
dict(x) | 将 x 转换为字典类型,x 必须是可迭代的键值对序列(如列表、元组)。 | dict([('a', 1), ('b', 2)]) → {'a': 1, 'b': 2} |
bool(x) | 将 x 转换为布尔类型,x 的值可以是任何对象,返回 True 或 False 。 | bool(0) → False ; bool("abc") → True |
frozenset(x) | 将 x 转换为冻结集合,x 必须是可迭代对象。 | frozenset([1, 2, 3]) → frozenset({1, 2, 3}) |
bytes(x) | 将 x 转换为字节串类型,x 可以是字符串、字节数组等。 | bytes("hello", "utf-8") → b'hello' |
complex(x) | 将 x 转换为复数类型。 | complex(2) → (2+0j) |
chr(x) | 将整数 x 转换为对应的字符,x 是 Unicode 码点。 | chr(97) → 'a' |
ord(x) | 将字符 x 转换为对应的整数,x 是一个单一字符。 | ord('a') → 97 |
eval(x) | 将字符串 x 作为 Python 表达式进行求值并返回结果。 | eval('3 + 4') → 7 |
set(x) | 将可迭代对象 x 转换为集合。 | set([1, 2, 2, 3]) → {1, 2, 3} |
注意事项:
-
并不是所有类型都可以直接转换。如:
int("hello") # 会抛出 ValueError: invalid literal for int() with base 10: 'hello'
-
类型转换可能会引发错误或丢失信息,比如浮点数转换为整数时,小数部分会丢失。
2. 运算符
运算符用于执行某种操作并返回一个结果,Python中的运算符可以分为:
2.1 算术运算符
用于执行基本的数学运算
2.1.1 常见运算符
-
+
:加法 -
-
:减法 -
*
:乘法 -
/
:除法 -
%
:取模(取余数) -
**
:幂运算 -
//
:整除(取整数部分)
2.1.2 课后练习
-
课后练习1
超市的西瓜 13 元一个, 问 你拿100 元可以买几个西瓜,剩余 几元
参考答案
print('可以买', 100 // 13 , '个西瓜,剩余', 100 % 13, '元')
-
课后练习2
现在是 18:02:31 秒 请问现在距离 凌晨 0:0:0 过了多少秒? 写程序打印出来
参考答案
second = 18 * 60 * 60 + 2 * 60 + 31 print('距离凌晨 0:0:0 过了', second, '秒')
2.2 比较运算符
用于比较两个值并返回布尔值 True 或 False
-
==
:等于 -
!=
:不等于 -
<
:小于 -
>
:大于 -
<=
:小于等于 -
>=
:大于等于
print(10==10.0)#只比较值是否相等:True print(3.14!=3.1415)#True print(255>170)#True print(255<170)#False print(255>=255)#True print(255<=255)#True x=15 print(5<x<20)#注意:两个符号同时参与比较 相当于 (5 < x) and (x < 20) x=100 y=200 z=-10 a=True print(a is not x is not y < z)#a和x判定 然后x和y判定 然后y和z判定,被解析为 (a is not x) and (x is not y) and (y < z)。 # False
在Python中,is not
是一种身份运算符,用于判断两个对象是否不是同一个对象。它与 is
运算符相对,后者用于判断两个对象是否是同一个对象。
具体来说:
-
a is b
返回True
当且仅当a
和b
是同一个对象(即它们的身份相同)。 -
a is not b
返回True
当且仅当a
和b
不是同一个对象(即它们的身份不同)
a = [1, 2, 3] b = a c = [1, 2, 3] print(a is b) # True,因为 a 和 b 是同一个对象 print(a is c) # False,因为 a 和 c 是不同的对象,即使它们的内容相同 print(a is not c) # True,因为 a 和 c 不是同一个对象
2.3 逻辑运算符
用于连接布尔值并返回布尔值
2.3.1 运算符
-
and
:与(逻辑与) -
or
:或(逻辑或) -
not
:非(逻辑非)
2.3.2 运算规则
-
and 与运算:两者同时为真,结果才为真
-
语法
x and y # x, y代表表达式
-
示例
3 + 4 > 5 and 6 + 7 > 100 False
-
真值表
x的值 y的值 x and y的值 True True True True False False False True False False False False 优先返回假值对象, 如果x 为假值,返回x, 否则返回y
A and B表达式的结果: 如果A表达式的布尔判定为真则B表达式的结果作为整个表达式的结果,如果A表达式的布尔判定为假则A表达式的结果作为整个表达式的结果
-
-
or 或运算:只要有一个为真,结果就为真
-
语法
x or y # x, y代表表达式
-
真值表
x的值 y的值 x or y的值 True True True True False True False True True False False False 优先返回真值对象, 如果x 为真值,返回x, 否则返回y
-
-
not 非运算:将表达式的结果取 非 操作
not 运算符是一元运算符
-
语法
not 表达式
-
示例
not True # False not False # True not 3.14 # False not '' # True not 1 + 2 # False
-
2.3.3 课后练习
写一个程序,输入一个整数, 判断这个整数是奇数还是偶数 奇数: 1 3 5 7 9 偶数: 2 4 6 8 10 x % 2 == 1 结果为True,x 一定是奇数 x % 2 == 1 结果为False,x 一定是偶数
2.4 赋值运算符
用于给变量赋值
-
=
:赋值 -
+=
:加法赋值 -
-=
:减法赋值 -
*=
:乘法赋值 -
/=
:除法赋值 -
%=
:取模赋值 -
**=
:幂运算赋值 -
//=
:整除赋值注意:
没有 a++、 a-- 这种自增自减运算符;
对于可变对象(如 list
, dict
, set
):a += 1
可能会修改原对象,而 a = a + 1
总是创建新对象:
a = [1, 2, 3] # a = a + [4] → 创建新列表 b = a a = a + [4] # 等价于 a = a.__add__([4]) print(a) # [1, 2, 3, 4] print(b) # [1, 2, 3] (b 不变) # a += [4] → 直接修改原列表(调用 a.__iadd__([4])) a = [1, 2, 3] b = a a += [4] # 等价于 a.extend([4]) print(a) # [1, 2, 3, 4] print(b) # [1, 2, 3, 4] (b 也被修改!)
2.5 位运算符
用于对整数按位进行操作
2.5.1 常见运算符
-
&
:按位与 -
|
:按位或 -
^
:按位异或 -
~
:按位取反 -
<<
:左移位 -
>>
:右移位
2.5.2 运算规则
-
按位与(&)
-
表达式:
a & b
-
功能:对于每一位,如果a和b的相应位都是1,则结果位为1,否则为0。
# 示例:计算两个二进制数的按位与 a = 0b1011 # 二进制表示的11 b = 0b1101 # 二进制表示的13 result_and = a & b # 计算两者之间的按位与 print(bin(result_and)) # 输出:0b1001 (十进制为9)
-
-
按位或(|)
-
表达式:
a | b
-
功能:对于每一位,只要a和b中至少有一位是1,则结果位为1,否则为0。
# 示例:计算两个二进制数的按位或 a = 0b1011 b = 0b1101 result_or = a | b # 计算两者之间的按位或 print(bin(result_or)) # 输出:0b1111 (十进制为15)
-
-
按位异或(^)
-
表达式:
a ^ b
-
功能:对于每一位,如果a和b的相应位不同(一个为1,另一个为0),则结果位为1,否则为0。
# 示例:计算两个二进制数的按位异或 a = 0b1011 b = 0b1101 result_xor = a ^ b # 计算两者之间的按位异或 print(bin(result_xor)) # 输出:0b110 (十进制为6)
-
-
按位取反(~):
-
表达式:
~a
-
功能:对操作数a的每一个二进制位进行取反,即将1变为0,0变为1。
-
注意: 补码原因: ~a=a转换为十进制后的数-1
# 示例:计算一个二进制数的按位取反 a = 0b1011 result_not = ~a # 计算a的按位取反 print(bin(result_not)) # 输出:-0b1100 # 按位取反需要注意补码问题,如上题 # 1011按32位表示为0000 0000 0000 0000 0000 0000 0000 1011(32 位补码表示) # 按位取反后为 1111 1111 1111 1111 1111 1111 1111 0100(32 位补码表示) # 要将补码还原到原码: # - 将补码的每一位取反 # - 在反码的基础上加 1 # 所以1111 1111 1111 1111 1111 1111 1111 0100的反码为: # 0000 0000 0000 0000 0000 0000 0000 1011 # 在反码上加1: # 0000 0000 0000 0000 0000 0000 0000 1100 # 由于补码最高位为1,表示是一个负数,所以最终结果为: # -0b1100,即-12
-
-
左移运算符(<<):
-
表达式:
a << b
-
功能:将a的二进制表示向左移动b位,左边移出的部分会被丢弃,右边空出的位置补零。相当于乘以$2^n$次方
# 示例:将一个二进制数向左移动两位 a = 0b1011 result_left_shift = a << 2 # 将a向左移动两位 print(bin(result_left_shift)) # 输出:0b101100 (十进制为44)
-
-
右移运算符(>>):
-
表达式:
a >> b
-
功能:
-
将a的二进制表示向右移动b位
-
对于无符号整数,右边移出的部分会被丢弃,左边空出的位置补零(通常补0);
-
对于有符号整数,右移时取决于具体实现,可能是算术右移(符号位扩展)或者逻辑右移(补0)。
-
同理,相当于除以2^n
# 示例:将一个有符号二进制数向右移动一位 a = -0b1000 # 十进制为-8 result_right_shift = a >> 1 # 将a向右移动一位 print(bin(result_right_shift)) # 输出:-0b100 (十进制为-4) # 对于无符号数的例子 unsigned_a = 0b1000 unsigned_result_right_shift = unsigned_a >> 1 print(bin(unsigned_result_right_shift)) # 输出:0b100 (十进制为4)
-
-
2.6 身份运算符
用于比较对象的内存地址(即身份)
-
is:判断对象是否相同
-
is not:判断对象是否不同
基础类型:值和类型都相同时,存在一个内存空间里面
a = 1 b = 1 print(a == b) #True, 比较的是值 print(a is b) #True, 比较的是内存地址,同一个值放在一个内存里面
基础类型:类型不同时就需要存放在两个内存空间里
a=1 b=1.0 a == b #True,值是相等的 a is b #False,需要放在两个内存空间里面,分别表示int和float
引用类型:有序列表
a = [1, 2, 3] b = [1, 2, 3] print(a == b) #True, 比较的是值 print(a is b) #False,比较的是内存地址
更多1:有序的列表list
a = [1, 2, 3] b = [1, 3, 2] print(a == b) #False,比较的是值,列表是有序的,值不同 print(a is b) #False,比较的是地址
更多2:无序的集合Set
a = {1, 2, 3} b = {1, 3, 2} print(a == b) #True,比较的是值,Set是无序的,所以值相同 print(a is b) #False,比较的是地址
更多3:无序的字典Dict
a = {'name': '张三', 'age': 10} b = {'age': 10, 'name': '张三'} print(a == b) #True,比较的是值,字典是无序的,所以值相同 print(a is b) #False,比较的是地址
2.7 成员运算符
用于检查一个值是否是某个集合的成员
-
in
:判断值是否存在于序列中 -
not in
:判断值是否不存在于序列中5 in [2, 34, 5, 67]
2.8 三目运算符
条件运算符、三元运算符
max = a if a>b else b #如果 a>b 成立,就把 a 作为整个表达式的值,并赋给变量 max; #如果 a> b 不成立,就把 b 作为整个表达式的值,并赋给变量 max。
一个有意思的例子:
b = 3 + 1, "3 > 2",print('AAA') if 1 > 2 else print("BBB"),2 + 2 print (b)
打印结果如下:
BBB (4, '3 > 2', None, 4)
-
1 > 2
是False
,所以执行else
分支的print("BBB")
-
因此会先输出
BBB
(这是函数的副作用,不是元组的一部分) -
print()
函数的返回值是None
,所以这个元素的值是None
2.9 优先级
更多的时候,我们借助()来明确优先级问题。
3. 表达式
表达式(expression)是由一个或多个操作数和运算符组成的。简单来说,表达式可以是任何会产生一个值的代码片段。
3.1 算术表达式
涉及数学运算的表达式。例如:
a = 5 b = 3 result = a + b # 加法 result = a / b # 除法 result = a // b # 地板除 result = a % b # 取余 result = a ** b # 幂运算
3.2 比较表达式
用于比较两个值,通常返回布尔值 True
或 False
。
a = 5 b = 3 result = a > b # 大于 result = a <= b # 小于等于
3.3 逻辑表达式
用于连接布尔值,返回布尔值 True
或 False
。
a = True b = False result = a and b # 逻辑与 result = a or b # 逻辑或 result = not a # 逻辑非
3.4 赋值表达式
将一个值赋给一个变量,通常用 =
运算符。
a = 5 # 赋值表达式 b = a + 3 # 计算并赋值
Python 3.8+ 引入了 海象运算符(:=
),这是一种新的赋值表达式,允许在表达式中直接给变量赋值:
if (n := len(data)) > 10: # 给n赋值并使用 print(f"列表长度大于10,长度为{n}")
3.5 成员表达式
用于检查一个值是否在序列、集合或字典中。
a = [1, 2, 3] result = 2 in a # 检查2是否在列表a中 result = 4 not in a # 检查4是否不在列表a中
3.6 身份表达式
用于比较两个对象的身份(即是否是同一个对象),返回布尔值。
a = [1, 2] b = a result = a is b # 判断a和b是否是同一个对象 result = a is not b # 判断a和b是否不是同一个对象
3.7 三元表达式
简化的 if-else
表达式,根据条件选择两个值之一。
a = 5 b = 3 result = a if a > b else b # 如果a > b,result为a,否则为b
3.8 调用运算符()
在 Python 中,圆括号也可以用来创建表达式,通常用于控制运算顺序或者在函数调用时传递参数。
result = (5 + 3) * 2 # 使用括号改变运算顺序
3.9 表达式的求值顺序
Python 中的表达式按照运算符优先级规则求值。运算符优先级的规则决定了不同类型的运算在计算时的顺序。
运算符 | 描述 |
---|---|
(expressions...) ,[expressions...] , {key: value...} , {expressions...} | 绑定或加圆括号的表达式,列表显示,字典显示,集合显示 |
x[index] , x[index:index] , x(arguments...) , x.attribute | 抽取,切片,调用,属性引用 |
** | 乘方 |
+x , -x , ~x | 正,负,按位非 NOT |
* , / , // , % | 乘,除,整除,取余 |
+ , - | 加和减 |
<< , >> | 移位 |
& | 按位与 AND |
^ | 按位异或 XOR |
| | 按位或 OR |
in, not in, is, is not, < , <= , > , >= , != , == | 比较运算,包括成员检测和标识号检测 |
not x | 布尔逻辑非 NOT |
and | 布尔逻辑与 AND |
or | 布尔逻辑或 OR |
if -- else | 条件表达式 |
lambda | lambda 表达式 |
:= | 赋值表达式 |
3.10 课后练习
result = 2 ** 3 ** 2,计算结果
x = 1 + 2 << 3,计算结果
4. 语句
语句是计算机执行程序的最小单位。
4.1 赋值语句
赋值语句将一个值赋给变量:
a = 5 # 将值 5 赋给变量 a b = a + 2 # 计算 a + 2 并将结果赋给 b
4.2 条件语句
条件语句用于根据不同的条件来执行不同的代码块。常见的条件语句有 if
、elif
和 else
:
语法
if 条件表达式1: 语句块1 elif 条件表达式2: 语句块2 ... elif 条件表达式n: 语句块n else: 语句块(其他)
小案例
x = 10 if x > 0: print("x 是正数") elif x == 0: print("x 是零") else: print("x 是负数")
4.3 循环语句
循环语句用于重复执行一段代码,直到满足某个条件。常见的循环语句有 for
循环和 while
循环。
4.3.1 for循环
遍历可迭代对象(如列表、元组、字典等)
遍历是指经历且只经历一遍
可迭代对象是指能够依次获取数据元素的对象
for i in range(5): print(i) # 输出 0, 1, 2, 3, 4
4.3.2 while循环
当条件为 $True$ 时重复执行
-
语法
while 真值表达式: 语句块1 (*此部分可能会重复执行) else: 语句块2
-
参考代码
count = 0 while count < 5: print(count) count += 1 # 输出 0, 1, 2, 3, 4
-
while循环是可以嵌套的
4.3.3 range
-
作用
用来生成一个能够得到一系列整数的可迭代对象(也叫整数序列生成器)
-
调用格式
range(stop) # stop 停止整数 range(start, stop) # start 开始整数 range(start, stop, step) # step 步长
range 函数调用会生成从 start 开始,到 stop 结束(不包含stop) 的一系列整数,整数的间隔 step
start 默认值为0, step 默认值为1