python学习第二周总结
阅读原文时间:2023年07月08日阅读:5

上周内容概要

  • 基本数据类型之布尔值

  • 基本数据类型至元组

  • 基本数据类型之集合

  • 与用户交互

  • 格式化输出

  • 基本运算符

  • 常用运算符

  • 逻辑运算符

  • 成员运算符

  • 身份运算符

  • 垃圾回收与机制

  • 流程控制理论

  • 流程控制之分支结构

  • 流程控制之循环结构

  • while循环补充说明

  • 流程控制至for循环

  • range方法

  • range实战案例

  • 数据类型内置方法

  • 整形相关操作

  • 浮点型相关操作

  • 字符串相关操作

  • 列表相关操作

  • 字典相关操作

  • 元组相关操作

  • 集合相关操作

  • 字符编码理论

  • ### 字符编码实操

上周内容详细

1.用于判断事务对错,是否可行,用于流程控制中

2.只有两种状态
    True:对的、真的、可行的
    False:错的、假的、不可行的

3.python中所有的数据库都自带布尔值
    布尔值为False的数据表:0 None ''(空字符串) [](空列表) {}(空字典)
    除以上数据类型外布尔值都是True

4.布尔值变量名命名规范:
    一般都以is开头
    eg:is_delete、is_alive

"""
很多用户程序的注销功能,其实都是修改了布尔值
"""


1.也称为'不可变'的列表:元组内部绑定的的内存地址不能修改。

2.小括号括起来,内部存放多个数据值,数据值与数据值之间用都逗号隔开,数据值可以是任意数据类型。

3.代码实现:(10, 10.12, 'max')

4.元组和列表对比:
    4.1元组和列表都可以通过索引取值
l1 = [1, 2.1, 'jason']
t1 = (1, 2.1, 'jason')
print(l1[1], t1[1])  # 2.1 2.1

    4.2.列表可以通过索引取值来修改内部数据值,元组不行
l1 = [1, 2.1, 'jason']
t1 = (1, 2.1, 'jason')
l1[1] = 2.2
print(l1)  # [1, 2.2, 'jason']
t1[1] = 2.2  # 还没打印就会报错

    4.3.元组不能通过索引来修改内部数据,但是因为列表是可变类型,修改之后内存地址并未改变,所以元组中的列表元素改变相当于元组中的数据值没有改变。
t1 = (1, 2.1, [0, 1, 2])
t1[2][1] = 2
print(t1)  # (1, 2.1, [0, 2, 2])

5.当元组内只有1个元素时,它的数据类型是它本身,加一个逗号之后数据类型是元组。所以以后含有多个数据值的数据类型如果只有一个数据值,最好在后面加上逗号。
# t1 = (11)
# t2 = (11,)
# print(type(t1), type(t2))  # <class 'int'> <class 'tuple'>

# t1 = (11.11)
# t2 = (11.11,)
# print(type(t1), type(t2))  # <class 'float'> <class 'tuple'>

# t1 = ('hello world')
# t2 = ('hello world',)
# print(type(t1), type(t2))  # <class 'str'> <class 'tuple'>


1.大括号括起来,内部存放多个数据值,数据值之间用逗号隔开,数据值不是K:V键值对。

2.集合只能用于去重和关系运算。

3.代码实现:
    s = {1, 2, 3, 4}

4.空集合和空字典;
    {}默认是字典
    set{}默认是集合

s1 = {}
s2 = set()
print(type(s1), type(s2))  # <class 'dict'> <class 'set'>


1.获取用户输入关键字:input
    username = input('请输入您的用户名>>>:')
    """
    原理:
    1.先执行input获取用户输入
    2.将获取到的用户输入赋值给username
    3.此后通过变量名username就可以找到用户输入的数据
    4.input获取到的用户数据都会转成字符串
    """

2. 输出内部信息
    2.1 print括号内可以存放变量名也可以存放数据值,并且支持多个,用逗号隔开即可。

    2.2 print自带换行符
        换行鬼:\r\n或\n(斜杠加字母会产生特殊含义)
      print('今天是个好天气\n明天也是个好天气')

    2.3print可以切换结束符,默认是\n
print('今天天气好好', end='$$$')
print('真棒')  # 今天天气好好$$$真棒

3.python2和python3区别
    3.1区别1::
    python2中获取用户输入需要用户自己编辑数据类型,写什么数据类型就是什么数据类型,写字符串要加双引号。
    python3写什么数据类型都会转换成字符串。python2中raw_input和python3作用一样。
    3.2区别2:
    python3中打印方式只有一种:print('变量名或数据值'),python2中除了和python3相同的一种,还有一种:print 数据值或变量名。


1.只有一个占位符:
s = '您好%s先生!!!'
print(s % 'max')  # 您好max先生!!!

user_name = input('请输入您的姓名>>>:')
user_gender = input('请输入您的性别>>>:')
if user_gender == 'male':
    print('您好%s先生' % user_name)
elif user_gender == 'female':
    print('您好%s女士' % user_name)
else:
    print('请输入正确性别')

2.多个占位符:
info = '您好%s先生,您本月的消费%s元,余额%s元'
print(info % ('max', 88, 100))  # 您好max先生,您本月的消费88元,余额100元
"""
有几个占位符就要有几个数据值,多了不行少了也不行
"""
3.%s和%d区别:%s可以替代任意数据类型,%d只能替代数字
# info1 = '您好%s先生,您本月的消费%s元,余额%s元'
# info2 = '您好%d先生,您本月的消费%d元,余额%d元'
# print(info1 % ('max', 88, 100))  # 您好max先生,您本月的消费88元,余额100元
# print(info2 % ('max', 88, 100))  # 报错:a number is required, not strs

4.%d其他用法:此种用法只适用于0开头的数字
print('%08d' % 12)  # 00000012
print('%016d' % 888) # 0000000000000888
print('%04d' % 85427)  # 85427,如果结尾的数字多于总数,结果就是结尾的数字


1.数学运算符
+ - * / %(取余) //(整除) **(指数)
简化写法:
n = 10
n += 2  # n = n + 2
n -= 2  # n = n - 2
n *= 2  # n = n * 3
n /= 2  # n = n / 2
n %= 2  # n = n % 2
n //= 2  # n = n // 2
n **= 2  # n = n ** 2

2.比较运算符:
> < >= <= ==(等于) !=(不等于)


1.链式赋值
age = 18
age1 = age
age2 = age1
age1 = age2 = age = 18

2.交叉赋值
m = 999
n = 111
m, n = n, m
print(m, n)  # 111 999

3.解压赋值
name1, name2, name3, name4 = ['jason', 'max', 'henry', 'jerry']
print(name1, name2, name3, name4)  # jason max henry jerry

name1, name2, *_ = ['jason', 'max', 'henry', 'jerry']
print(name1, name2, _)  # jason max ['henry', 'jerry']

*_, name1 = ['jason', 'max', 'henry', 'jerry']
print(name1, _)  # jerry ['jason', 'max', 'henry']


1.and
    1.1and连接多个条件同时成立结果才成立,只要发现一个不成立,结果就不成立。
    1.1左右都为比较运算符时都正确才成立。
print(1<2 and 2<3): True
print(5<4 and 6<7): False

    1.2 and前面的条件成立,后面的结果是什么就是什么(数据值或者布尔值)。前面的条件不成立,结果直接为False。

2.or
    2.1or前面的条件成立,结果直接为前面的结果(布尔值或数据值),or前面的条件不成立,后面的结果是什么就是什么。
print(111 or 6 < 4)  # 111
print(111 or 6 > 4)  # 111
print(6>7 or 111)  # 111
print(0 or False)  # False 前面的不成立,后面的是什么就是什么
print(6>7 or 0)  # 0

3.not:用法为取反

"""
三者混合使用若没有括号时,优先级为not,and,or
"""


1.列表判断:列表判断的最小单位是列表的元素
l1 = ['jason', 'max', 'tony']
print('jason' in l1)  # True
print('j' in l1)  # False

2.字符串判断:字符串判断的最小单位是字符
s = 'hello world'
print('h' in s)  # True

3.3.字典判断:字典判断只有K参与
    d1 = {
      'username': 'jason',
      'pwd': 123
}
    print('username' in d1) #True
    print('jason' in d1) #False


1.print(id(变量名)),返回一串数字是内存地址

2.is: 判断内存地址是否相同
==: 判断数据值是否相同
# l1 = [1, 2, 3, 4, 5]
# l2 = [1, 2, 3, 4, 5]
# print(id(l1))
# print(id(l2))
# print(l1 == l2) #True
# print(l1 is l2) #False
"""
结论:数据值相同,内存地址不一定相同;内存地址相同,值一定相同
"""


"""
有一些语言内存空间的申请和释放需要程序员写代码才能完成,但是python不需要,通过垃圾回收机制自动管理
"""
1.引用计数
    name = 'max'  #数据值'max'的引用计数为1
    name1 = name  #数据值'max'的引用计数为2
    数据值被变量名引用的次数称为引用计数。当引用计数为0时,该数据值就会被垃圾回收机制清理回收。当引用计数不为0,该数据值不会被垃圾回收机制回收。

2.标记清除
针对循环引用问题:
    l1 = [1, 2, 3] #引用计数为1
    l2 = [4, 5, 6] #引用计数为2
    l1.append(l2) #l1 = [1, 2, 3, l2列表]
    l2.append(l1) #l2 = [4, 5, 6, l1列表]
    del l1  #断开变量名l1与列表的绑定关系
    del l2  #断开变量名与l2列表的绑定关系
     当内存占用达到顶峰是,程序就会自动停止,然后扫描程序中所有数据并给产生循环引用的数据打上标记,然后一次性清除

3.分代回收
    把数据值按照检索频率分为几类(定义为新生代、青春代、老年代),每隔一段时间对数据值的引用频率进行检索,同样时间段内引用频率越高检索频率越低,说明该数据越重要。


流程控制:控制事务的执行流程
事物的执行流程可以分为三类:
    1.顺序结构
        从上往下依次执行,我们之前编写的的代码都属于顺序结构。
    2.分支结构
        事物的执行会根据条件的不同做出不同的执行策略
    3.循环结构
        事物的执行会根据各种条件出现反复的循环
 """
 1.在代码的世界里很多时候会出现上述三种情况的混合
 2.应把代码和流程图有机结合
 """


1.python中使用代码的缩进来表示代码的从属关系
    缩进的代码称为子代码,上面一行没有缩进的代码称为它的父代码,子代码是否执行取决于上面的父代码。
2.并不是所有的代码都可以有子代码,在流程控制中if可以有。
3.如果几行代码同属于一行父代码的子代码,则它们应该拥有相同的缩进量。
4.python中没有要求缩进量是几个空格,但是在python中推荐使用4个空格(windows中一个tab键)。
5.如果一行代码拥有子代码,在它的最后要有冒号(英文模式下)。
6.如果几行代码拥有相同的父代码(拥有相同的缩进量),则它们之间应该平起平坐,按照顺序执行。


1.单if分支结构:分支结构只有一条路可以走。
语法结构:
if 条件:
    条件成立执行的代码

user_name = input('请输入我的名字>>>:')
    if user_name == '大帅比':
        print('一般一般')

2.if...else...分支结构:分支结构有两条路可以走(一次只能走一条,两条不可能同时走)
if 条件:
    条件成立执行的子代码
else:
    条件不成立执行的子代码
    score = input('请输入你的分数>>>:')
    score = int(score)
    if score >= 80:
        print('勉勉强强 继续努力')
    else:
        print('学个毛线回去摊煎饼吧')    

3.if...elif..else.分支结构:
    if 条件1:
        条件1成立执行的子代码
    elif 条件2:
        条件1不成立条件2成立执行的子代码
    elif 条件3:
        条件1、2都不成立,条件3成立执行的子代码
    else:
        上述条件都不成立执行的子代码
"""
1.上述elif可以有多个
2.上述代码一次只能走一条路径
3.如果把下面的elif换成if,那么结果是上面的if执行完毕会接着执行下面的if,而不是像elif,if执行elif就不会执行。
"""
user_score = input('请输入您的分数>>>:')
user_score = int(user_score)
if user_score >= 90:
    print('nb啊老铁你是我学习榜样')
elif user_score >= 80:
    print('厉害厉害都是大神')
elif user_score >= 70:
    print('小心点我努努力可能就超过你了哦!')
else:
    print('明天摊煎饼咱俩搭伙吧')

4.if的嵌套使用


就是想让一些代码反复执行
语法结构:
while 条件:
    条件成立执行的代码(循环体代码)
1.先判断条件是否成立
2.如果条件成立则执行循环体代码
3.循环体代码执行完毕再回到条件判断处,判断条件是否成立
4.如果条件成立则继续执行循环体代码
5.遵循上述规规律直到条件不成立

break:强行结束循环体代码

continue:while循环体代码一旦执行到continue就会结束本次循环,开始下一次循环

while...else:
    循环体代码没有被强制结束的情况下,执行完毕之后就会执行else子代码,如果while子代码被break或continue强制退出则不会执行else子代码。


1.死循环:
    靠自身控制无法终止的循环。死循环一旦执行,CPU能耗 急剧上升,直到系统采取紧急措施,

2.嵌套及全局标志位
    一个break只能结束它本层所在的while循环,想要结束多层while循环需要用到多个break,并且结束上一层的break要和本层的while有相同的缩进量。如果想一次性结束多层while,可以用到全局标志位。开头用一个变量名替代布尔值,在某个条件下将变量名对应的布尔值由True改为False,即可结束全部的while循环。

is_alive = True
while is_alive:
    user_name = input('请输入您的用户名>>>:')
    user_pwd = input('请输入您的密码>>>:')
    if user_name == 'max' and user_pwd == '123':
        while is_alive:
            order = input('请输入您的指令>>>:')
            if order != 'q':
                print('正在执行您的指令%s' % order)
            else:
                print('欢迎下次光临')
                is_alive = False
    else:
        print('用户名或密码错误')


1.for循环能做到的事情while都可以做到,但是for循环在某些场景下更简单

2.for循环使用的主要场景为:循环获取多个数据内部数据值。

3.for循环语法结构:
for 变量名 in 待遍历数据
    for循环体代码

4.for循环特点:
    1.擅长遍历取值
    2.不需要结束条件,遍历结束之后自动结束

5.for循环体可以遍历的数据类型有:字符串、列表、字典(字典遍历只有K参与,同成员运算)、元组、集合

6.for循环语法结构中的变量名命名规则:
    1.见名知意
    2.如果遍历出来的数据没有特殊含义,可以直接使用i,j,k,item,v

7.for循环体代码如果遇到break也会直接结束整个for循环
for i in rang  e(0,21):
    if i == 10:
        break
    print(i)  #结果:打印1-9,i = 10时break会结束整个for循环

8.for循环遇到continue也会直接结束当前循环直接开始下一次循环

9.for循环也可以和else连用,语法结构为:
for 变量名 in 待遍历数据:
    for循环体代码
else:
    遍历结束之后并且没有被break或者continue打断的情况下运行



range可以理解为是一个帮我们产生很多数字的数据

1.for i in range(100):
    print(i)
# 打印0-99的数字,左边不写默认从0开始,左包含右不包含
2.for i in range(1,100)
# 打印1-99的数字,左包含右不包含

3.for i in range(0,25,5)
# 0,5,10,15,20,前两个数字是范围,左包含右不包含,第三个数字是间隔

"""
python2和python3的区别:
python2中range()会产生一个列表,比如range(10)会打印结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],python3中的range()和python2中的xrange()都会打印一个集合,range(10)打印结果为range(0,10),python2中打印结果为xrange(10)
"""


网络爬虫
    使用代码爬取网络上我们需要的数据
项目需求
    爬取所有页面的数据(博客园)
找寻规律
    https://www.cnblogs.com/
     https://www.cnblogs.com/#p2
     https://www.cnblogs.com/#p3
     https://www.cnblogs.com/#p4

     大胆猜测:第一页是 https://www.cnblogs.com/#p1
编写代码产生博客园文章前两百页的网址

addr = 'https://www.cnblogs.com/#p%s'
for i in range(1, 201):  #for循环, i此时是1-200的所有数字
    print(addr % i) #格式化输出

'''
分页的规律 不同的网址有所区别
    1.在网址里面有规律
    2.内部js文件动态加载
'''


1.每一种数据类型本身都含有一系列的操作方法,内置方法是其本身自带的功能,是其中最多的。

2.python中数据类型调用的内置方法的统一句式为:数据类型.数据类型内置方法


1.类型转换(将其他类型转化成整形)
语法结构:变量名 = int(其它数据类型) print(变量名)

1.1浮点型转化成整形:结果只取前面整数部分,没有四舍五入
# num = 2.19
# print(int(num))  # 2
# num = 10.98
# print(int(num))  # 10

1.2字符串转化成整形:字符串中要是整数,可以直接去掉引号转化成字符串,字符串中若是小数会报错
# s = '47'
# print(int(s))  # 47
# s = '1.11'
# print(int(s))  # 报错

2.进制数转换
2.1十进制转其他进制:
关键字:转二进制:bin,转八进制:oct,转十六进制:hex
进制数前缀:二进制:0b,八进制:0o, 十六进制:0x
print(bin(12))  # 0b1100
print(oct(12))  # 0o14
print(hex(12))  # 0xc

2.2其他进制转十进制:int()
print(int('0b1100', 2))  # 12
print(int('0o14', 8))  # 12
print(int('0xc', 16))  # 12


1.类型转换

语法结构:float(其他数据类型)
整数转化成浮点型:小数点后面保留一位。字符串转换成浮点型:字符串中是整形:去掉引号之后小数点后面保留一位;字符串中是浮点型直接把引号去掉。
# num = 22
# print(float(num))  # 22.0
# num = '22'
# print(float(num))  # 22.0
# num = '22.1'
# print(float(num))  # 22.1

2.python对数字敏感程度

python对数字敏感程度较低,如果需要进行计算需要借助模块numpy



1.类型转化
任意数据类型都可以转化为字符串,语法结构:str(其它数据类型)
print(str(11))  # '11'
print(str('11.11'))  # '11.11'
print(str([1, 2, 2]))  # '[1, 2, 2]'
print(str({'name': 'max',}))  # '{'name': 'max'}'

2.索引取值
"""
索引取值
"""
s = '今天天气真好'
print(s[2])  # 天
print(s[-1])  # 好

3.切片操作
s = 'artificial intelligence'
# print(s[1:4])  # rti
# print(s[-5:-1])  # genc
# print(s[-1:-5])  # 不会打印,因为方向默认从左往右

4.修改切片方向、间隔
s = 'artificial intelligence'
print(s[1:6:2])  # rii
print(s[-1:-5:-1])  # ecne
print(s[:])  # artificial intelligence,默认打印所有字符
print(s[2:])  # tificial intelligence,默认从索引值为2的字符开始打印
print(s[:4])  # arti,从开头打印到索引值为3的字符
print(s[::2])  # 从头开始打印,间隔为2

5.统计字符串中总字符个数
s = 'artificial intelligence'
print(len(s))  # 23

6.移除字符串首尾指定字符
关键字:strip()
括号内未输入字符时默认移除空格。若只想移除左右一侧的指定字符,可以用lstrip或lstrip()
s = '%artificial intelligence%%'
print(s.strip('%'))  # artificial intelligence
print(s.rstrip('e%%'))  # %artificial intelligenc
print(s.lstrip('%'))  # artificial intelligence%%

7.切割字符串中指定字符
7.1可以按照字符串中某个字符把字符串切割成几段,并组成一个列表
s = 'max|123|soccer'
print(s.split('|'))  # ['max', '123', 'soccer']

7.2可以控制切割的方向和个数。split()默认从左往右切,rsplit()是从右往左切,maxsplit用来控制方向
s = 'max|123|soccer|engineer|Gansu'
print(s.split('|'))  # ['max', '123', 'soccer', 'engineer', 'Gansu']
print(s.split('|', maxsplit=2))  # ['max', '123', 'soccer|engineer|Gansu']
print(s.rsplit('|', maxsplit=2))  # ['max|123|soccer', 'engineer', 'Gansu']

8.字符串格式化输出
8.1format用法1:字符串中用{}当做占位符,占位符个数和format括号内的数据值要相等
s = 'my name is {},my age is {}'
print(s.format('max', 25))

8.2format用法2:大括号冲充当占位符,里面写索引值,索引值对应format中的数据值,可以反复使用
s = 'my name is {0}, my age is{1}, my hobby is {2}.{0} love {2} '
print(s.format('max', 25, 'soccer'))

8.3format用法3:大括号充当占位符,里面写变量名,format括号内写明变量名和数据值对应的关系,支持反复使用
s = """
my name is {name}, my age is {age}, my hobby is {hobby},{name}
aged {age} loves {hobby}
"""
print(s.format(name='max', age=25, hobby='soccer'))

8.4format用法4:获取用户输入然后使用,print(f'打印内容,需要替换的内容用大括号括起来,内部含有获取用户输入的变量名')
user_name = input('请输入您的用户名>>>:')
user_age = input('请输入您的年龄>>>:')
print(f'大家好我是{user_name},我今年{user_age}岁')
"""
常用操作:
将获取用户输入得到的字符串合并成一个字符串,用'|'链接:
user_name = input('请输入您的用户名>>>:')
user_age = input('请输入您的年龄>>>:')
user_data = f'{user_name}|{user_age}'
"""

9.字符串大小写转化
9.1大小写转化,关键字:upper(),lower()
s = 'Artificial Intelligence'
print(s.upper())  # ARTIFICIAL INTELLIGENCE
print(s.lower())  # artificial intelligence

9.2图片验证码练习题:
code = '8Ja6Cc'
print('验证码', code)
confirm_code = input('请输入验证码>>>:')
if confirm_code.upper() == code.upper():
    print('登陆成功')
else:
    print('登陆失败')

9.3判断字符串中字符是否是纯大写或纯小写,判断结果是布尔值
关键字:islower()、 isupper()
s = 'artificial intelligence'
print(s.islower())  # True
print(s.isupper())  # False

10.判断字符串是否是纯数字(整数),只有字符串可以执行此操作,其他数据类型执行不了
关键字:isdigit
s = '54'
print(s.isdigit())  # True

11.替换字符串中指定的字符
关键字:repalce(),括号内前面的参数是原字符串中的字符,后面是要提换成的字符,如果指定替换的个数在第三个数字上体现,只能从左往右替换。
s = 'artificial intelligence'
res = s.replace('i', '%')
print(res)  # art%f%c%al %ntell%gence
res1 = s.replace('i', '%', 2)
print(res1)  # art%f%cial intelligence

12.字符串的拼接
12.1 两个字符串凭借可以直接用+
'''字符串的拼接'''
s1 = 'aitificial'
s2 = 'intellgence'
s = s1 + s2
print(s)  # aitificialintellgence
拼接是也可以自己手动增加字符
s1 = 'aitificial'
s2 = 'intellgence'
s = s1 + s2
print(s)  # aitificialintellgence
print(s1 + ' ' + s2)  # aitificial intellgence
print(s1 + '%' + s2)  # aitificial%intellgence

12.2关键字join()
语法结构: '指定字符'.join(列表变量名)。把列表通过指定字符拼接成一个字符串,是split的反向操作,列表中的元素必须都是字符串
l1 = ['max', '25', 'soccer', 'engineer']
print('|'.join(l1))  # max|25|soccer|engineer

13.统计字符串中指定字符出现的个数
语法结构:print(字符串.count('指定字符'))
s = 'artificial intelligence'
print(s.count('i'))  # 5

14.判断字符串的开头和结尾
语法结构:print('字符串'.startswith('指定字符'))、print('字符串'endswith('指定字符'))。结果是布尔值。
s = 'artificial intelligence'
print(s.startswith('a'))  # True
print(s.endswith('nce'))  # True

15.字符串中每个单词首字母大写
关键字:title()
s3 = 'hala mardid hala mardid'
print(s3.title())  # Hala Mardid Hala Mardid

16.大小写反转
关键字:swapcase()
s = 'arTificial intelligence'
print(s.swapcase())  # ARtIFICIAL INTELLIGENCE

17.第一个单词首字母大写
关键字:capitalize()
print()
s = 'arTificial intelligence'
print(s.capitalize())  # Artificial intelligence

18.根据字符查找索引值
语法结构:print(index())、print(find())
print(s.index('i'))  # 3
print(s.find('i'))  # 3
查找的若是字符串中没有的字符,index()会报错,find()会打印-1
print(s.index('b'))  # 报错
print(s.find('b'))  # -1



1.索引取值,最后一个数据值索引值是-1
l = [1, 2, 3, 4, 5, 6]
print(l[2])  # 3
print(l[-1])  # 6

2.切片操作、间隔数、方向(同字符串)
l1 = [0, 2, 3, 5, 6, 7, 8, 90, 345, 21]
print(l1[1:3])  # [2, 3]
print(l1[-1:-5])  # []  方向不对,不打印,但不报错
print(l1[-1:-5:-1])  # [21, 345, 90, 8]
print(l1[-5:-1])  # [7, 8, 90, 345]
print(l1[::])  # [0, 2, 3, 5, 6, 7, 8, 90, 345, 21] 打印所有数据值
print(l1[2::])  # [3, 5, 6, 7, 8, 90, 345, 21]
print(l1[:-1:])  # [0, 2, 3, 5, 6, 7, 8, 90, 345]
print(l1[::2])  # [0, 3, 6, 8, 345]

3.统计列表中数据值的个数
语法结构:print(len(变量名))
l1 = [0, 2, 3, 5, 6, 7, 8, 90, 345, 21]
print(len(l1))  # 10  

4.数据值修改
通过索引直接修改,打印时打印原变量名
l1 = [0, 2, 3, 5, 6, 7, 8, 90, 345, 21]
l1[3] = 8
print(l1)  # [0, 2, 3, 8, 6, 7, 8, 90, 345, 21]

5.列表添加数据值
5.1在尾部添加数据值:
语法结构:append(任意数据类型)
l1 = [0, 2, 3, 5, 6, 7, 8, 90, 345, 21]
l1.append([1, 2, 3])
print(l1)  # [0, 2, 3, 5, 6, 7, 8, 90, 345, 21, [1, 2, 3]]

5.2在任意位置添加数据值:
语法结构:insert(索引值, 任意数据类型)
l1 = [0, 2, 3, 5, 6, 7, 8, 90, 345, 21]
l1.insert(2, 'jason')
print(l1)  # [0, 2, 'jason', 3, 5, 6, 7, 8, 90, 345, 21]

5.3扩展、合并列表
可以用两个列表直接相加,相加过程中可以加自己手动输入的列表
l1 = [1, 2, 3]
l2 = [4, 5, 6]
print(l1 + l2)  # [1, 2, 3, 4, 5, 6]
print(l1 + l1 + [1, 1, 1])  # [1, 2, 3, 1, 2, 3, 1, 1, 1]

entend
l1.extend(l2)
print(l1)  # [1, 2, 3, 4, 5, 6]

6.删除列表数据
关键字del
l1 = ['jason', 'max', 'henry', 'david']
del l1[0]
print(l1)  # ['max', 'henry', 'david']

关键字pop():默认弹出最后一个数据值,如果用变量名命名可以使用。括号内可以写索引值
l1 = ['jason', 'max', 'henry', 'david']
res = l1.pop()
print(l1, res)  # ['jason', 'max', 'henry'] david

关键字remove():不能像pop一样弹出后使用,括号内要直接写数据值
l1 = ['jason', 'max', 'henry', 'david']
l1.remove('jason')
print(l1)  # ['max', 'henry', 'david']

7.排序,默认是升序,降序要在括号内加(reverse=True)
l1 = [1, 34, 45, 26, 43, 675, 3467, 35, 23, 5]
l1.sort()
print(l1)  # [1, 5, 23, 26, 34, 35, 43, 45, 675, 3467]
l1.sort(reverse=True)
print(l1)  # [3467, 675, 45, 43, 35, 34, 26, 23, 5, 1]

8.统计列表中数据值出现的个数
语法结构:print(变量名.(数据值))
l1 = [0, 2, 3, 5, 6, 2, 8, 2, 345, 21]
print(l1.count(2))  # 3

9.颠倒列表顺序
l1 = [0, 2, 3, 5, 6, 2, 8, 2, 345, 21]
l1.reverse()
print(l1)  # [21, 345, 2, 8, 2, 6, 5, 3, 2, 0]



1.可变类型:调用内置方法之后内存地址没有改变,修改之后没有产生新的结果。列表、字典、集合都是可变类型。

2.不可变类型:调用内置方法之后内存地址改变,修改之后产生新的结果,需要在左边添加变量名和赋值符号。整形、浮点型、字符串、元组都是不可变类型。


1.类型转换:dict(),字典转换一般不使用关键字,而是自己手动转。

2.字典掌握的操作:
    1.按K取值(不推荐):打印的K不存在会报错
user_dict = {'user_name': 'max', 'user_age': 25, 'hobby': 'soccer'}
print(user_dict['hobby'])  # soccer
print(user_dict['job'])  # 键不存在则报错

    2.按内置方法get取值(推荐使用)
括号内只有一个参数时,若K存在于字典内则打印K对应的V,不存在则打印None不会报错。
print(user_dict.get('user_name'))  # max
print(user_dict.get('job'))  # None,键不存在不会报错会打印None
括号内有两个参数,若K存在则打印K对应的值,K不存在则打印括号内后面的参数
print(user_dict.get('user_name', 'K存在会发生什么'))  # max
print(user_dict.get('job', 'K不存在会发生什么'))  # K不存在会发生什么

    3.修改键值对
键值对存在则通过键修改对应的值,修改之后字典的内存地址未变,因此字典是可变类型。
user_dict = {'user_name': 'max', 'user_age': 25, 'hobby': 'soccer'}
print(id(user_dict))
user_dict['hobby'] = 'sleep'  # 2152821906176
print(user_dict, id(user_dict))  # {'user_name': 'max', 'user_age': 25, 'hobby': 'sleep'} 2152821906176

    4.新增键值对
键不存在则新增键值对
user_dict = {'user_name': 'max', 'user_age': 25, 'hobby': 'soccer'}
user_dict['job'] = 'programmer'
print(user_dict)  # {'user_name': 'max', 'user_age': 25, 'hobby': 'soccer', 'job': 'programmer'}

    5.删除数据
del关键字:del后跟键值对的K,K:V键值对会同时删除
user_dict = {'user_name': 'max', 'user_age': 25, 'hobby': 'soccer'}
del user_dict['hobby']
print(user_dict)  # {'user_name': 'max', 'user_age': 25}

pop()关键字:pop()括号内存放K,删除时会删掉此K:V键值对。用变量名给pop()关键字命名,可以通过此变量名直接找到对应的值
res = user_dict.pop('user_age')
print(user_dict, res)  # {'user_name': 'max', 'hobby': 'soccer'} 25

    6.统计字典中键值对的个数:
关键字:len()
user_dict = {'user_name': 'max', 'user_age': 25, 'hobby': 'soccer'}
print(len(user_dict))  # 3

    7.字典三剑客:
关键字:keys(),values(),items()
user_dict = {'user_name': 'max', 'user_age': 25, 'hobby': 'soccer'}
print(user_dict.keys())  # dict_keys(['user_name', 'user_age', 'hobby'])
print(user_dict.values())  # dict_values(['max', 25, 'soccer'])
print(user_dict.items())  # dict_items([('user_name', 'max'), ('user_age', 25), ('hobby', 'soccer')])

for k, v in user_dict.items():
    print(k,v)
# user_name max
# user_age 25
# hobby soccer   # 元组也可以解压赋值

    8.关键字fromkeys:快速生成值相同的字典
print(dict.fromkeys(['username', 'age', 'hobby'], 'max'))  # {'username': 'max', 'age': 'max', 'hobby': 'max'}
l1 = [1, 2, 3, 4]
print(dict.fromkeys(l1, 222))  # {1: 222, 2: 222, 3: 222, 4: 222}

面试题:第二个公共值时可变类型的时候,通过任何一个键修改都会影响所有
d1 = dict.fromkeys(['username', 'age', 'hobby'], [])  # d1:{'username': [], 'age': [], 'hobby': []}
d1['username'].append('max')
d1['age'].append(25)
d1['hobby'].append('soccer')
print(d1)  # {'username': ['max', 25, 'soccer'], 'age': ['max', 25, 'soccer'], 'hobby': ['max', 25, 'soccer']}



1.类型转换:
    tuple(),支持for循环的数据类型都可以转成元组
2.必须掌握的操作:
    1.索引取值
    2.切片操作
    3.间隔、方向
    4.统计元组内元素的个数 len()
    5.统计元组内数据值出现的个数 count()
    6.统计元组内指定数据值的索引值 index(),find()
    7.元组内如果只有一个元素那么逗号不能少
    8.元组内绑定的索引地址不能被修改(如果元祖中有元素是列表,列表是可变类型,修改之后内存地址不变,所以元组内元素的内存地址也不会改变)
    9.元组不能新增或删除数据


1.类型转换:
    set()
    集合内数据是无序的,没有索引的概念(同字典)

2.集合需要掌握的方法:
    1.去重
    2.关系运算

3.去重:列表转化成集合去重之后顺序会发生改变
s1 = {11, 22, 11, 22, 22, 11, 222, 11, 22, 33, 22}
l1 = list(s1)
s1 = set(l1)
print(s1)  # {33, 11, 222, 22}

4.关系运算
s1 = {'jason', 'max', 'henry', 'kiki'}
s2 = {'jason', 'kitty', 'max', 'jerry'}
print(s1 & s2)  # {'jason', 'max'}
print(s1 | s2)  # {'kiki', 'jerry', 'henry', 'kitty', 'max', 'jason'}
print(s1 - s2)  # {'kiki', 'henry'}
print(s1 ^ s2)  # {'kiki', 'henry', 'jerry', 'kitty'}


1.字符编码只针对文本数据
2.计算机内部存储数据的本质:在内存申请一块地方将数据值和变量名绑定在一起,此后通过该变量名就可以直接找到数据值
3.既然计算机内部只认识01 为什么我们却可以敲出人类各式各样的字符
    肯定存在一个数字跟字符的对应关系 存储该关系的地方称为>>>:字符编码本
4.字符编码发展史
    4.1.一家独大
        计算机是由美国人发明的 为了能够让计算机识别英文
        需要发明一个数字跟英文字母的对应关系
        ASCII码:记录了英文字母跟数字的对应关系
            用8bit(1字节)来表示一个英文字符

     4.2.群雄割据
        中国人
        GBK码:记录了英文、中文与数字的对应关系
               用至少16bit(2字节)来表示一个中文字符
                很多生僻字还需要使用更多的字节
           英文还是用8bit(1字节)来表示
       日本人
          shift_JIS码:记录了英文、日文与数字的对应关系
        韩国人
         Euc_kr码:记录了英文、韩文与数字的对应关系
          """
          每个国家的计算机使用的都是自己定制的编码本
              不同国家的文本数据无法直接交互 会出现"乱码"
          """
      4.3.天下一统
        unicode万国码
             兼容所有国家语言字符
                起步就是两个字节来表示字符
          utf系列:utf8 utf16 ...
            专门用于优化unocide存储问题
            英文还是采用一个字节 中文三个字节



1.存在乱码时可尝试切换编码
2.编码与解码
    编码:将人类的字符按照指定的编码编码成计算机能够读懂的数据
        字符串.encode()
     解码:将计算机能够读懂的数据按照指定的编码解码成人能够读懂
        bytes类型数据.decode()
3.python2与python3差异
    python2默认的编码是ASCII
        1.文件头
            # encoding:utf8
        2.字符串前面加u
            u'你好啊'
     python3默认的编码是utf系列(unicode)