基本数据类型
数字类型
整形int
作用:记录年龄、个数等等
定义:
>>> age = 18
>>> print(type(age))
<class 'int'>
浮点型float
作用:记录薪资、身高、体重
定义:
salary = 3.3
height = 1.87
weight = 70.3
print(type(height))
数字类型的其他使用
level = 1
level = level + 1
print(10 * 3)
int与float之间可以相加
print0(10 + 3.3)
比较大小
>>> x = 10
>>> y = 11
>>> x > y
false
字符串类型str
作用:记录描述性质的状态,名字、一段话
定义:用引号(‘ ’,“ ”,‘’‘ ’‘’,“”“ ”“”)包含的一串字符串
info = '''
'''
其他使用:
要输出 my name is ‘egon’
字符串的嵌套要注意:
外层用单引号,内层应该用双引号,反之也可
“my name is ‘egon’”
或者使用 \ 进行转义
’my name is \’egon\‘’
字符串之间可以相加,但仅限于str与str之间进行
代表字符串的拼接,了解即可,不推荐使用,因为str之间的相加效率极低
>>> print('='*10)
==========
列表类型
索引对应值,索引从0开始,0代表第一个
作用:按位置记录多个值(同一个人的多个爱好、同一个班级的所有学生姓名),并且可以按照索引取指定位置的值
定义:在[]内用逗号分隔开,多个任意类型的值,一个值称之为一个元素
l = [1,2.3,'aaa',['bbb','sasad']]
print(l[3][0])
其他用途:
students_info = [
['tony',18,['jack',]],
['jason',18,['play','sleep']]
]
# 取出第一个学生的第一个爱好
print(students_info[0][2][0])
字典类型
索引反应的是顺序、位置,对值没有描述性的功能
字典类型:key对应值,其中key通常为字符串类型,所以key对值可以有描述性的功能
作用:用来存多个值,每个值都有唯一一个key与其对应,key对值有描述性作用
定义:在{}内用逗号分开各多个key:value
字典当中列表没有顺序,默认无序
d = {"a":1,"b":2}
print(d['a'])
info = {
"name":'egon',
"age":18,
"gender":'male',
"salary":19
}
print(info["salary"])
其他用途:
students_info = [
{"name":'egon1',"age1":19,"gender":'male'},
{"name":'egon2',"age1":19,"gender":'male'},
{"name":'egon3',"age1":19,"gender":'male'},
]
print(students_info[1]['gender'])
布尔类型
>>> is_ok = True
>>> is_ok = False
students = [
{"name":'egon',"gender":1}, # 可以用1代表男,用0代表女
{"name":'egon',"gender":0},
]
print(students[0]["gender"])
垃圾回收机制(GC机制)
引用计数
x = 10
print(x)
# 直接引用
l = ['a',x]
print(l[1]) # 间接引用
专门用来回收不可用的变量值所占用的内存空间
标记清除
l1 = [111,]
l2 = [222,]
l1.append(l2) # 将l2的内容加入到l1的列表中 l1=[值111的内存地址,l2列表的内存地址]
l2.append(l1) # 将l1的内容加入到l2的列表中 l2=[值222的内存地址,l1列表的内存地址]
# 循环引用
print(l1)
del 111
del 222
# 不要相互引用,可能无法清除111和222的内存,成为了永远不能清理的内存垃圾
# 111和222之间存在间接引用,在python运行的一段时间后会自行扫描清理内存。
内存:
1、栈区:存放变量名
2、堆区:存放变量赋值
3、其他区
python的扫描清除会将间接引用而无直接引用的内存给清除
分代回收
基于引用计数的回收机制,每次回收内存,都需要把所有对象的引用计数都遍历一遍,这是非常消耗时间的,于是引入分代回收来提高回收效率,分代回收采用的是用“空间换时间”的策略。
分代回收的核心思想是:在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低。
用户交互
# 接收用户的输入
username = input("请输入您的账号:")
print(username,type(username))
# input会将用户输入的所有内容都存成字符串类型
而要比较大小等使用整型,则需要转换变量类型
age = input("请输入你的年龄:")
print(age,type(age))
age = int(age) # int只能将纯数字的字符串转成整型
print(age > 16)
以上是在python3中使用
而在python2中,有raw_input():用法与python3的input一模一样
python2
input():要求用户必须输入一个明确的数据类型,输入的是什么类型,就存成什么类型
格式化输出
%号
res = "my name %s my age is %s" %('egon',"18")
print(res)
百分号有几个,就应该传几个,多和少都会报错
值按照位置与%一一对应,少一个不行,多一个也不行
# 以字典的形式传值,打破位置的限制
res = "我的名字是 %(name)s 我的年龄是 %(age)s" %{"name":'egon',"age":'18'}
print(res)
%s规定是接收字符串,但可以接收任意类型
%d只能接收int,否则会报错
str.format
兼容性好,2.6以上版本均可使用
res = '我的名字是 {0}{0}{0} 我的年龄是 {1}{1}'.format('egon',18)
print(res)
# 打破位置限制,按照key=value传值
res = '我的名字是 {name} 我的年龄是 {age}'.format(age = 18,name = 'egon')
print(res)
推荐用此方法
f
python3.5以后才推出
x = input('your name: ')
y = input('your age: ')
res = f'我的名字是{x} 我的年龄是{y}'
print(res)
速度快慢:f > str.format >%号
基本运算符
算数运算符
print(10 + 3.1)
print(10 + 3) # 大部分情况下使用在数字之间
print(10 / 3) # 结果带小数
print(10 // 3) # 只保留整数部分,不四舍五入
print(10 % 3) # 取模、取余数
print(10 ** 3) # 取模、取余数
比较运算符
>、>=、<、<=、==、!=
运算符 | 描述 |
---|---|
== | 比较两个对象是否相等 |
!= | 比较两个对象是否不相等 |
> | 大小比较,例如 x>y 将比较 x 和 y 的大小,如 x 比 y 大,返回 True,否则返回 False |
< | 大小比较,例如 x<y 将比较 x 和 y 的大小,如 x 比 y 小,返回T rue,否则返回 False |
>= | 比较两个对象是否相等大小比较,例如 x>=y 将比较 x 和 y 的大小,如 x 大于等于 y,返回 True,否则返回 False |
<= | 大小比较,例如 x<=y 将比较 x 和 y 的大小,如 x 小于等于 y,返回 True,否则返回 False |
赋值运算符
变量赋值
=
:变量赋值
增量赋值
age = 18
age = age + 1
print(age)
# 简写
age += 1
print(age)
链式赋值
x = 10
y = x
z = y
print(x,y,z)
print(id(x),id(y),id(z))
# 将以上直接改为
x = y = z = 10
print(x,y,z)
print(id(x),id(y),id(z))
交叉赋值
# 交换值
m = 10
n = 20
temp = m
m = n
n = temp
print(m,n)
# 交叉赋值
m,n = n,m
print(m,n)
解压赋值
解压字典默认解压出来的是字典的key
salaries = [111,222,333,444,555]
# 把五个月的工资取出来分别赋值给不同的变量名
mon0 = salarie[0]
mon1 = salarie[1]
mon2 = salarie[2]
mon3 = salarie[3]
mon4 = salarie[4]
print(mon0)
print(mon1)
print(mon2)
print(mon3)
print(mon4)
# 解压赋值
mon0,mon1,mon2,mon3,mon4 = salaries # 对应的变量名多一个少一个都不行
print(mon0)
print(mon1)
print(mon2)
print(mon3)
print(mon4)
# 引入*,可以帮助我们取两头的值,无法取中间的值
# 只想取前三个值
x,y,z,*_ = salaries
# *会将之后所有未赋值的内容接收,赋值给_,通常代表指废掉的变量
# *会将没有对应关系的值存成列表赋值给其后的那个变量名,此处为_
可变不可变类型
可变类型:值改变,id不变,证明改的是原值
不可变类型:值改变,id也改变,证明是产生新的值,压根没有改变原值,证明原值是不可以被修改的
x = 10
print(id(x)) # 140732069316560
x= 11 # 产生新值
print(id(x)) # 140732069316592
int是不可变类型
x = 3.1
print(id(x)) # 1374472465200
x= 3.2
print(id(x)) # 1374470243344
float是不可变类型
x = "abc"
print(id(x)) # 2011990575024
x= "aaaa"
print(id(x)) # 2011990672112
str是不可变类型
int、float、str都被设计成了不可分割的整体,不能够被改变
l = ['a','b','c']
print(l)
print(id(l))
l[0] = 'A'
print(l)
print(id(l))
列表是可变类型,将列表内的任意内容修改,列表id不会改变
dic = {'k1':111,'k2':222}
print(id(dic))
dic['k1'] = 222
print(id(dic))
字典是可变类型
布尔bool不可变
关于字典补充
定义:{}内用逗号分隔开多key:value,其中value可以是任意类型
dic = {
'k1':222,
'k2':1.1
'k3':[333,],
'k4':{'name':'egon'}
}
key只能是不变类型
条件判断
显式布尔值
条件可以是:比较运算符
age = 18
print(age > 16) # 条件判断之后会得到一个布尔值
条件可以是:True、False
is_beautiful = True
print(is_beautiful)
隐式布尔值
所有的值都可以当成条件去用
其中0、None、空(空字符串、空列表、空字典) → 代表的布尔值为False,其余都为True
逻辑运算符
not:把紧跟其后的条件结果取反
与紧跟其后的条件是一个不可分割的整体
print(not 16 > 13)
and:逻辑与,and用来链接左右两个条件,两个条件同时为True,最终结果才为真
print(True and 10 > 3)
or:逻辑或,or用来链接左右两个条件,两个条件但凡有一个为True,最终结果就为True
优先级
not > and > or
如果单独就是只是一串and链接,或者说单独就只是一串or链接,按照从左到右的顺序依次运算即可
如果混用,则考虑优先级
(3 > 4 and (not 4 > 3)) or (1==3 and 'x' == 'x') or 3 > 3
# 提取语句
成员运算&身份运算
print('egon' in 'hello egon') # 判断一个字符串是否存在与一个大字符串中
print('e' in 'hello egon') # 判断一个字符串是否存在与一个大字符串中
判断key是否存在于字典
print(111 in {"k1":111,"k2":222}) # False
print("k1" in {"k1":111,"k2":222}) # True
not in 不存在返回True
print("egon" not in "hello egon") # 推荐使用
print(not "egon" in "hello egon") # 逻辑同上,但语义不明确,不推荐使用
身份运算符
is:判断的是id是否相等
流程控制
if判断
语法1:
if 条件:
代码1
代码2
代码3
同一级别代码,会按照自上而下的顺序依次执行
age = 18
is_beautiful = True
star = '水瓶座'
if (age > 16 and age < 20 and is_beautiful and star == '水瓶座'):
print('我喜欢,我们在一起吧....')
print('其他代码......')
语法2:
if 条件:
代码1
代码2
代码3
else:
代码1
代码2
代码3
age = 60
is_beautiful = True
star = '水瓶座'
if (age > 16 and age < 20 and is_beautiful and star == '水瓶座'):
print('我喜欢,我们在一起吧....')
else:
print("阿姨好,我逗你玩呢,深藏功与名")
语法3:
if 条件:
代码1
代码2
代码3
elif 条件2:
代码1
代码2
代码3
elif 条件3:
代码1
代码2
代码3
score = input('请输入您的成绩: ')
score = int(score)
if score >= 90:
print('优秀')
elif score >= 80:
print('良好')
elif score >= 70:
print('普通')
语法4:
score = input('请输入您的成绩: ')
score = int(score)
if score >= 90:
print('优秀')
elif score >= 80:
print('良好')
elif score >= 70:
print('普通')
else:
print('很差')
深浅copy
list1 = [
'egon',
'lxx',
[1,2]
]
# 二者分割不开,list1改list2也跟着改,因为指向的都是同一个地址
list2 = list1
list1 = [
'egon',
'lxx',
[1,2]
]
# 二者分割不开,list1改list2也跟着改,因为指向的都是同一个地址
list2 = list1
# 需求:
# 1、拷贝一下原列表,产生一个新的列表
# 2、想让两个列表完全独立开,针对的是改操作的独立而不是读操作的独立
浅copy
是把原列表第一层的内存地址不加区分完全copy一份给新列表
list1 = [
'egon',
'lxx',
[1,2]
]
list2 = list1.copy()
print(list2)
print(id(list1))
print(id(list2))
# 两个列表的id并不相同
如果原列表中存放的全都是不可变类型,则对新列表没有影响,但是如果存在可变类型,则会对新列表有影响
深copy
可以区分可变类型与不可变类型的copy机制
import copy
list1 = [
'egon',
'lxx',
[1,2]
]
list2 = copy.deepcopy(list1)
深copy后的新列表内存地址均不一样,无论是不可变类型还是可变类型
总结
浅copy只是copy的第一层,而忽略了第二层的不可变类型
深copy会对不可变类型和可变类型进行加以区分
while循环
count = 0
while count < 5:
print(count)
count += 1
print('顶级代码----->')
while可以称为条件循环
死循环与效率问题
死循环本身是无害,纯计算无io的死循环会导致致命的效率问题
while True:
name = input('your name >>>> ')
print(name)
while循环应用
inp_name = input('请输入您的账号: ')
inp_pwd = input('请输入您的密码: ')
if inp_name == 'egon' and inp_pwd == '123':
print('登陆成功')
else:
print('账号名或密码错误')
使用if没办法循环,可以用while
# 两个问题
# 1、重复代码
# 2、书对了应该不用再重复
while 1:
inp_name = input('请输入您的账号: ')
inp_pwd = input('请输入您的密码: ')
if inp_name == 'egon' and inp_pwd == '123':
print('登陆成功')
else:
print('账号名或密码错误')
循环结束方式一
将条件改成False,等到下次循环判断条件时才会生效
tag = True
while tag:
inp_name = input('请输入您的账号: ')
inp_pwd = input('请输入您的密码: ')
if inp_name == 'egon' and inp_pwd == '123':
print('登陆成功')
tag = False
else:
print('账号名或密码错误')
循环结束方式二
break,只要运行到break就会立刻终止本层循环
while tag:
inp_name = input('请输入您的账号: ')
inp_pwd = input('请输入您的密码: ')
if inp_name == 'egon' and inp_pwd == '123':
print('登陆成功')
break # 立刻终止本层循环
else:
print('账号名或密码错误')
while循环嵌套
'''
# 每一层都必须配一个break
while True:
while True:
while True:
break
break
break
tag = True
while tag:
while tag:
while tag:
'''
使用break结束循环,需要每一层都使用break结束循环
while+continue
结束本次循环,直接进入下一次
在continue之后添加同级代码毫无意义,因为永远无法运行
count = 0
while count < 6:
if count == 4:
count += 1
continue
print(count)
count += 1
while+else
else包含的代码会在while循环结束后,并且while循环是在没有被break打断的情况下正常结束的,才会运行
若中途有break打断,则不会运行else内的代码
else针对break结束的while嵌套循环
count = 0
username = 'egon'
password = '123'
tag = True
while tag:
if count == 3:
print('输错超过3次')
break
inp_name = input('请输入您的账号: ')
inp_pwd = input('请输入您的密码: ')
if inp_name == username and inp_pwd == password:
print('登陆成功')
while tag:
cmd = input('输入命令>: ')
if cmd == 'q':
tag = False
else:
print('命令{x}正在运行'.format(x = cmd))
else:
print('账号名或密码错误')
count += 1
count = 0
username = 'egon'
password = '123'
while count < 3:
inp_name = input('请输入您的账号: ')
inp_pwd = input('请输入您的密码: ')
if inp_name == username and inp_pwd == password:
print('登陆成功')
while True:
cmd = input('输入命令>: ')
if cmd == 'q': # 整个程序结束,退出所有while循环
break
else:
print('命令{x}正在运行'.format(x = cmd))
break
else:
print('账号名或密码错误')
count += 1
else:
print('输错3次,退出') # 此处的条件是:只能count=3时才会执行
总结
break不是属于同一级while的子代码,而是上一级while的子代码
因此break是结束的上一级循环
continue之后不要写同级的运行代码,continue是结束本次循环,直接进入下一次循环
for循环
定义
循环就是重复做某件事,for循环时python提供的第二种循环机制,第一种是while循环。
理论上for循环能做的事情,while循环都可以做,之所以要有for循环,是因为for循环在循环取值(遍历取值)比while循环更简洁
语法
可迭代对象可以是:列表、字典、字符串、元组、集合
'''
for 变量名 in 可迭代对象:
代码1
代码2
代码3
...
'''
while可以成为条件循环,循环多少次取决于条件,而for循环可以成为迭代循环,根据可迭代对象有多少,循环多少次
# 案例1:循环取值
# 简单版
l = ['alex_dsb','lxx_dsb','egon_nb']
for x in l:
print(x)
# 复杂版:
l = ['alex_dsb','lxx_dsb','egon_nb']
i = 0
while i < 3:
print(l[i])
i+=1
# 案例2:字典循环取值
# 简单版
dic = {'k1':111,'k2':222,'k3':333}
for k in dic:
print(k,dic[k])
# 复杂版:while循环可以遍历字典,但是太麻烦
# 案例3:字符串循环取值
# 简单版
msg = "you can you up,no can no bb"
for x in msg:
print(x)
总结
for循环与while循环的异同:
相同之处:都是循环,for循环可以干的事,while循环也可以干
不同之处:
while循环成之为条件循环,循环次数取决于条件何时变为假
for循环称之为“取值循环”,循环次数取决于in后包含的值的个数
for循环控制循环次数range
range( 10):生成10个从0到9的列表
range(1,9):从1生成到8,共九个数
range(1,9,1):第三个参数为步长,默认为1
for i in range(30):
print('===>')
username = 'egon'
password = '123'
for i in range(3):
inp_name = input('请输入您的账号: ')
inp_pwd = input('请输入您的密码: ')
if inp_name == username and inp_pwd == password:
print('登陆成功')
break
else:
print('输错账号密码次数过多')
range补充
l = ['aaa','bbb','ccc'] # len(l)
for i in range(len(l)):
print(i,l[i])
for循环也可以按照索引取值,len()
用来取列表内的包含的值的个数
for+continue
for i in range(6):
if i == 4:
continue
print(i)
for循环嵌套
外层循环循环一次,内层循环需要完整的循环完毕
终止 for循环只有break一种方案
for i in range(3):
print('外层嵌套-->',i)
for j in range(5):
print('内层-->',j)
print补充
print('hello %s' % 'egon')
# 会打印“hello egon”
print('hello\n')
# \n换行符
print('hello',end='*')
# 后加end,用来取消print自带的换行
参与讨论