基本数据类型

数字类型

整形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自带的换行