程序=数据+功能
数据是程序的核心。存数据是为了取数据。
一. 变量
1.1 变量使用原则
先定义,后调用。
1.1.1 定义阶段
age=18
定义过程由变量名,赋值符号,变量值组成。
变量定义过程的成分 | 作用 |
---|---|
变量名 | 用来找值 |
赋值符号 | 将变量值的内存地址绑定给变量名 |
变量值 | 存储的数据,记录事物的状态 |
整个变量定义过程是这样的:
先在内存中申请内存空间用来存放变量值,将内存空间的内存地址绑定给变量名。
1.1.2 引用阶段
print(age) #--->18
1.2 变量命名规范
给变量命名的大前提是“见名知意”
- 变量名由数字,字母和下划线组成。
- 不能由数字开头。
- 不能出现python关键字。
print=123
print(print)
>>>TypeError: 'int' object is not callable
1.3 变量值
1.3.1 变量值的两大特征
-
查询类型
age=18 salary=20.0 print(type(age),type(salary)) # ---> <class 'int'> <class 'float'>
-
查询id
id就是值在内存中的身份证号,反应的就是内存地址。print(id(age),id(salary)) # --->140734502695728 2001710795184
如果两个变量的id一样,说明它们位于相同的内存地址。
is:判断id(内存地址)是否相等
==:判断值是否相等注意:如果id相等,那么值一定相等。
x=10 y=x print(id(x),id(y)) # --->1833428634000 1833428634000 print(x is y) #c--->True #(基于pycharm平台的运行结果)
但其实在pycharm中,由于内置文件的优化,出现了小整数池的概念。即pycharm预先开辟了
一些内存空间存储常用的数字和字符串。当这些数字被调用时,直接给他们分配内存地址,提高
了程序运行的效率。
1.3.2 内存管理
内存管理主要涉及的是垃圾回收机制(gc)。
垃圾回收机制的核心原理是统计引用计数。通过统计引用计数,标记清除和分代回收机制来提高对内存的使用效率。
首先引入堆区和栈区的概念:
栈区存放的是变量名和内存地址的关系,可以简单理解为,变量名存内存地址。
堆区存放的是变量值。
强调:只站在变量名的角度去谈一件事情。
变量名的赋值(x=10)还有变量名的传参(print(x)),传递的都是内存中栈区的数据。而栈区的数据是对变量名和内存地址的对应关系。
python是引用传递。
同时应该避免循环引用(一般发生于容器数据类型相互应用)。
列表是如何存储的呢
二. 基本数据类型
2.1 整型 int
不可分割,一个整体
整数,作用可以描述年龄,数量,号码。
age=18
number=20
count=32
2.2 浮点型 float
不可分割,一个整体
小数,作用身高,体重,薪资。
height=1.74
weight=80.3
salary=2.5
2.3 字符串 str
不可分割,一个整体
位于 ’ ’ 或 “ ” 之间的字符,作用是描述性质的内容。
name='wth'
position="boss"
message='''
wo
de
tian'''
字符串的转义,在对应的符号前面\
,例如'/' '
。
导语:正是因为前面三种介绍的数据类型都是不可分割的数据类型,所以引入了可以收入多值的容器型
数据类型。当我们想一次性将很多数值存储起来的时候,数字类型和字符串类型已经很难满足。
2.4 列表 list
位于 [ ] 之间的字符,按照位置存放多个值,这些值属于同一属性。
l=['123',123,[1,2],'yong']
print(l[0],l[-1],l[-2][0]) # --->123 yong 1
导语:列表可以解决存放同种属性的值的问题,当出现了不同属性的多个值需要被存储的时候,列表已经
不能高效的存储这些数据,需要新的数据类型来解决这个问题。
2.5 字典 dict
位于 { } 之间的数值或者字符,存放不同属性的元素。每个元素由 key:value 组成。key 通常是字符串类型,value可以是任何类型。作用:按照 key 存放多个值,key反映的是value的属性。
d={'name':'egon','age':18,'gender':[1,2,3],'salary':{'123':2}}
print(d['name'],d['salary']['123']) # ---> ‘egon' 2
一个列表字典合用的案例:存放多个同学的信息。
方案一:
students=[
{'name': 1,'gender':'male','age':18},
{'name': 2, 'gender': 'male', 'age': 18},
{'name': 3, 'gender': 'female', 'age': 18},
{'name': 1, 'gender': 'male', 'age': 18}]
取数据的时候,描述为“取第二个学生的姓名”。通过描述也可以反推是如何建立数据的,列表嵌套字典。
方案二:
stud={
'wth1': {'age':'18', 'phone': 188, 'sex': 'male'},
'wth2': {'age':'19','phone': 186, 'sex': 'female'},
'wth3': {'age':'20','phone': 205, 'sex': 'female'},
'wth4': {'age':'21','phone': 238, 'sex': 'male'}}
取数据的时候,描述为“取姓名为xxx的性别”。通过描述同样可以反推数据是如何建立的,字典嵌套字典。
2.6 布尔值 bool
不可分割,一个整体
作用:布尔值并不是直接调用,而是应用于真假状态的应用。
x=True
y=False
print(x,y,type(x),type(y))
三. 基本运算符
3.1 算术运算符
算术运算符包括的运算有
+,-,*,/,**,%,//
算术运算符一般应用于数字类型(整型和浮点型)中,对数据进行操作。比如:
print(10+1) # ---> 11
print(10-1) # ---> 9
print(10*2) # ---> 20
print(10/3) # ---> 3.333333334
print(10**3) # ---> 1000
print(10%3) # ---> 1
print(10//3) # --->3
ps: + 和 * 也可以应用到字符串中,但由于是申请新的内存地址存储新生成的字符串,所以不经常使用字符串的 + 和 * 操作。
3.2 比较运算符
比较运算用来对两个值进行比较,返回的是布尔值True或False。
比较运算符包括的运算有
==,>,<,>=,<=,!=
只有当数值类型相同,值也相同的时候,才是True
m=10
n='10'
print(m==n) # --->False
3.3 赋值运算符
python语法中除了有=
这种简单的赋值运符,还支持增量赋值、链式赋值、交叉赋值、解压赋值,这些赋值运算符存在的意义都是为了让我们的代码看起来更加精简。
3.3.1 链式赋值
当想同时对多个变量赋予相同的值时,使用这种赋值方法。
x=y=z=100
3.3.2 增量赋值
当记录变量递进的变化状态时,使用这种赋值方法。
3.3.3 交叉赋值
当想要交换两个变量的值(可以是数字类型,可以是字符串类型、列表类型、字典类型)时,使用这种赋值方法。
x='123'
y='456'
x,y=y,x
print(x,y) # ---> '456' '123'
3.3.4 解压赋值
顾名思义,想要将一个容器类型数据结构打开解压出来里面的值时,使用这种数据类型。
l=[1,2,3,4,5,6]
x,y,z,u,v,w=l
print(x,y,z,u,v,w) # ---> 1 2 3 4 5 6
可以一次取到容器数据类型中的每个值,也可以按照需求只取前几个,后面几个或者前面几个值和后面几个值。用*收集不想被解压赋值的值,绑定给__这个变量名。
# 只取前n个值:
x1,x2,*__=[1,2,3,4,5,6]
print(x1,x2,_) # ---> 1 2 [3,4,5,6]
# 只取后面n个值:
*__,x3,x4=[1,2,3,4,5,6]
print(_,x3,x4) # ---> [1,2,3,4] 5 6
同时取前n个值和后m个值:
x1,*__,x4=[1,2,3,4,5,6]
print(x1,_,x4) # ---> 1 [2,3,4,5] 6
字符串、字典、元组、集合类型都支持解压赋值。列表可以取到对应位置的值,字典只能取得key的值。
3.4 逻辑运算符
3.4.1 连续多个and
可以用and
连接多个条件,会按照从左到右的顺序依次判断,一旦某个条件为False
,可以立即判定最终结果就为False
,只有在所有条件的结果都为True
的情况下,最终结果才为True
。
2 > 1 and 1 != 1 and True and 3 > 2 # 判断完第二个条件,就立即结束,得的最终结果为False
3.4.2 连续多个or
可以用or
连接多个条件,会按照从左到右的顺序依次判断,一旦某一个条件为True
,则无需再往右判断,可以立即判定最终结果就为True
,只有在所有条件的结果都为False
的情况下,最终结果才为False
。
3.4.3 优先级not > and > or
#1、三者的优先级关系:not>and>or,同一优先级默认从左往右计算。
3>4 and 4>3 or 1==3 and 'x' == 'x' or 3 >3 # --->False
#2、最好使用括号来区别优先级,其实意义与上面的一样
'''
原理为:
(1) not的优先级最高,就是把紧跟其后的那个条件结果取反,所以not与紧跟其后的条件不可分割
(2) 如果语句中全部是用and连接,或者全部用or连接,那么按照从左到右的顺序依次计算即可
(3) 如果语句中既有and也有or,那么先用括号把and的左右两个条件给括起来,然后再进行运算
'''
(3>4 and 4>3) or (1==3 and 'x' == 'x') or 3 >3 # ---> False
#3、短路运算:逻辑运算的结果一旦可以确定,那么就以当前处计算到的值作为最终结果返回
10 and 0 or '' and 0 or 'abc' or 'egon' == 'dsb' and 333 or 10 > 4
我们用括号来明确一下优先级
(10 and 0) or ('' and 0) or 'abc' or ('egon' == 'dsb' and 333) or 10 > 4
短路: 0 '' 'abc'
假 假 真
返回: 'abc'
#4、短路运算面试题:
>>> 1 or 3
1
>>> 1 and 3
3
>>> 0 and 2 and 1
0
>>> 0 and 2 or 1
1
>>> 0 and 2 or 1 or 4
1
>>> 0 or False and 1
False
3.5 成员运算符
3.6 身份运算符
需要强调的是:==双等号比较的是value是否相等,而is比较的是id是否相等。
#1. id相同,内存地址必定相同,意味着type和value必定相同
#2. value相同type肯定相同,但id可能不同,如下
x='Info Tony:18'
y='Info Tony:18'
id(x),id(y) # x与y的id不同,但是二者的值相同
# ---> (4327422640, 4327422256)
x == y # 等号比较的是value
# ---> True
type(x),type(y) # 值相同type肯定相同
# ---> (<class 'str'>, <class 'str'>)
x is y # is比较的是id,x与y的值相等但id可以不同
# ---> False