变量

  • 什么是变量?

变量可以理解为名字,变量是存储在内存中的值。Python中的变量赋值不需要类型声明。

每个变量在内存中创建,都包括变量的标识,名称和数据这些信息。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。

等号=用来给变量赋值。等号=运算符左边是一个变量名,等号=运算符右边是存储在变量中的值。

>>> list1 = [1, 2, 3, 4, 5, 6]>>> print(list1)[1, 2, 3, 4, 5, 6]

在定义变量名时,需要注意变量名可读性要强,这样在看到变量名时容易理解存储在变量中的值。

  • 变量的命名规则:
  1. 变量名中只能由字母、数字、下划线组成

  2. 变量名的首字母不能是数字,可以是字母或下划线

  3. Python的保留关键字不能用在变量名中

  4. Python的变量名区分大小写

>>> if = 1SyntaxError: invalid syntax>>> and = 2SyntaxError: invalid syntax>>> import = 3SyntaxError: invalid syntax

  • 值类型与引用类型:

Python中的变量无类型,对象有类型。Python中的变量都是指针,可以指向任意对象。

在Python中,数值(整型,浮点型),布尔型,字符串,元组属于值类型,本身不允许被修改(不可变类型)。

在Python中,列表,集合,字典是引用类型,本身允许修改(可变类型)。

不可变对象类型:

int
float
decimal
complex
bool
str
tuple
range
frozenset
bytes

可变对象类型:

list
dict
set
bytearray
user-defined classes (unless specifically made immutable)

例子:

>>> a = 1>>> b = a>>> a = 3>>> print(b)1

>>> a = [1, 2, 3, 4, 5]>>> b = a>>> a[0] = '1'>>> print(a)['1', 2, 3, 4, 5]>>> print(b)['1', 2, 3, 4, 5]

比较上面两个例子,为什么会产生这种情况呢?

因为第一个例子是把int类型赋值给了变量a,而int类型为值类型,不可变,所以变量b为1;而第二个例子中是把list类型赋值给了变量b,list类型为引用类型,可变,所以变量b随着变量a的改变而改变。

  • 列表的可变与元组的不可变:

列表的可变:

>>> a = [1, 2, 3]>>> id(a)2245520284552>>> a[0] = '1'>>> id(a)2245520284552>>> a['1', 2, 3]

元组的不可变:

>>> b = (1, 2, 3)>>> b[0] = '1'Traceback (most recent call last):
  File "", line 1, in <module>
    b[0] = '1'TypeError: 'tuple' object does not support item assignment>>> b(1, 2, 3)

>>> c = (1, 2, 3, ['a', 'b', 'c'])>>> c[2] = '3'Traceback (most recent call last):
  File "", line 1, in <module>
    c[2] = '3'TypeError: 'tuple' object does not support item assignment>>> c[3] = ['aa', 'bb', 'cc']Traceback (most recent call last):
  File "", line 1, in <module>
    c[3] = ['aa', 'bb', 'cc']TypeError: 'tuple' object does not support item assignment>>> c[3][1] = 'bbb'>>> print(c)(1, 2, 3, ['a', 'bbb', 'c'])

可以看到,元组没有改变,改变的是列表。元组中的元素不可改变,但当元组中的元素是引用类型时,该元素内部是可变的。


运算符

>>> 1 + True2>>> 1 - False1


赋值运算符

赋值运算符是用来赋值的。

假设变量a的值10,变量b的值是20,则

运算符描述示例
=将右侧操作数的值分配给左侧操作数c = a + b表示将a + b的值分配给c
+=将右操作数相加到左操作数,并将结果分配给左操作数c += a等价于 c = c + a
-=从左操作数中减去右操作数,并将结果分配给左操作数c -= a 等价于 c = c - a
*=将右操作数与左操作数相乘,并将结果分配给左操作数c *= a 等价于 c = c * a
/=将左操作数除以右操作数,并将结果分配给左操作数c /= a 等价于 c = c / a
%=将左操作数除以右操作数的模数,并将结果分配给左操作数c %= a 等价于 c = c % a
**=执行指数(幂)计算,并将值分配给左操作数c **= a 等价于 c = c ** a
//=运算符执行地板除运算,并将值分配给左操作数c //= a 等价于 c = c // a

比较(关系)运算符

比较(关系)运算符比较它们两边的值,并确定它们之间的关系,结果是布尔值。它们也称为关系运算符。

假设变量a的值10,变量b的值是20,则

运算符描述示例
==如果两个操作数的值相等,则条件为真(a == b)求值结果为 false
!=如果两个操作数的值不相等,则条件为真(a != b)求值结果为 true
>如果左操作数的值大于右操作数的值,则条件成为真(a > b)求值结果为 false
<如果左操作数的值小于右操作数的值,则条件成为真(a < b)求值结果为 true
>=如果左操作数的值大于或等于右操作数的值,则条件成为真(a >= b)求值结果为 false
<=如果左操作数的值小于或等于右操作数的值,则条件成为真(a <= b)求值结果为 true
>>> [1, 2, 3] < [2, 3, 4]True>>> (1, 2, 3) < (2, 3, 4)True>>> {1, 2, 3} < {2, 3, 4}False>>> {1, 2, 3} > {2, 3, 4}False>>> {1, 2, 3} == {2, 3, 4}False>>> {1: 1, 2: 2, 3: 3}  < {2: 2, 3: 2, 4: 4}Traceback (most recent call last):
  File "", line 1, in <module>
    {1: 1, 2: 2, 3: 3}  < {2: 2, 3: 2, 4: 4}TypeError: '<' not supported between instances of 'dict' and 'dict'


逻辑运算符

逻辑运算符的操作对象和结果都是布尔类型。str与int类型能够转换为bool类型。

假设变量a的值为True,变量b的值为False,则

运算符描述示例
and逻辑与,如果两个操作数都为真,则条件为真(a and b) 的结果为False
or逻辑或,如果两个操作数中的任何一个为真,则条件为真(a or b) 的结果为True
not逻辑非,用于反转操作数的逻辑状态not(a and b) 的结果为True
>>> 1 or 21>>> 1 and 22>>> not 3False>>> not 0True

>>> 'a' and 'b''b'>>> 'a' or 'b''a'>>> not 'c'False>>> not ''True

>>> not []True>>> [1] or [][1]>>> [] or [1][1]

str、list、int、float类型能够转换为bool类型:

1. 对于int、float类型来说,非0表示True,而0表示False

2. 对于str类型来说,非空字符串表示True,空字符串表示False

3. 对于list类型来说,非空列表表示True,空列表表示False

4. 对于and、or,涉及到短路逻辑时会返回第一个值,否则返回第二个值


成员运算符

成员运算符测试给定值是否为序列中的成员,例如字符串、列表、元组、集合和字典。成员运算符的返回值是布尔类型。

运算符描述示例
in如果在指定的序列中找到一个变量的值,则返回true,否则返回false-
not in如果在指定序列中找不到变量的值,则返回true,否则返回false-
>>> b = 1>>> b in [1, 2, 3, 4, 5]True>>> b not in [1, 2, 3, 4, 5]False>>> b not in (1, 2, 3, 4, 5)False>>> b not in {1, 2, 3, 4, 5}False>>> b in {'a': 1}False>>> b = 'a'>>> b in {'a': 1}True

对于字典类型来说,成员运算符判断的是key-value中的key。


身份运算符

身份运算符比较两个对象的内存位置,比较两个对象的身份是否相等。身份运算符的返回值仍然是布尔类型。

运算符描述示例
is如果运算符任一侧的变量指向相同的对象,则返回True,否则返回False-
is not如果运算符任一侧的变量指向不同的对象,则返回True,否则返回False-
>>> a = 1>>> b = 1.0>>> a == bTrue>>> a is bFalse

>>> c = (1, 2, 3)>>> d = (2, 1, 3)>>> c == dFalse>>> c is dFalse

>>> e = {1, 2, 3}>>> f = {2, 1, 3}>>> e == fTrue>>> e is fFalse

元组是有序的,集合是无序的。

关系运算符==比较的是两个对象的值是否相等,而身份运算符is比较的是两个对象的身份是否相等。

Python中一切都是对象,对象有三个特征:值value、身份id、类型type。

前面判断了对象的值和身份,那么判断对象的身份呢?Python有一个内置函数isinstance()用于判断对象的类型,返回值是布尔类型。

>>> a = 'hello'>>> isinstance(a, str)True>>> isinstance(a, int)False>>> isinstance(a, (int, str, float))True


位运算符

位运算符把数当做二进制数执行逐位运算。Python的内置函数bin()可用于获取整数的二进制表示形式。

假设变量a = 60;和变量b = 13。现在以二进制格式,它们将如下

a = 0011 1100

b = 0000 1101

-----------------

a&b = 0000 1100

a|b = 0011 1101

a^b = 0011 0001

~a = 1100 0011

运算符描述示例
&按位与,如果它存在于两个操作数中,则操作符复制位到结果中(a & b) 结果表示为 0000 1100
|按位或,如果它存在于任一操作数,则复制位(a | b) = 61 结果表示为 0011 1101
^按位异或,二进制异或。如果它是一个操作数集合,但不是同时是两个操作数则将复制位(a ^ b) = 49 结果表示为 0011 0001
~按位取反,二进制补码,它是一元的,具有“翻转”的效果(~a ) = -61有符号的二进制数,表示为1100 0011的补码形式
<<左移动,二进制左移,左操作数的值由右操作数指定的位数左移a << 2 = 240 结果表示为 1111 0000
>>右移动,二进制右移,左操作数的值由右操作数指定的位数右移a >> 2 = 15 结果表示为 0000 1111

运算符优先级

下表列出了从最高优先级到最低优先级的所有运算符。

序号运算符描述
1**指数(次幂)运算
2~ + -补码,一元加减(最后两个的方法名称是+@-@)
3* / % //乘法,除法,模数和地板除
4+ --
5>> <<向右和向左位移
6&按位与
7^ |按位异或和常规的“OR
8<= < > >=比较运算符
9<> == !=等于运算符
10= %= /= //= -= += *= **=赋值运算符
11is is not身份运算符
12in not in成员运算符
13not or and逻辑运算符