python学习-基础-day2-模块列表字符编码
一、PYC文件
python首次执行某个文件,会生成一个pyc的编译文件,下次执行的时候首先会找是否有pyc文件,再检查文件日期,这样会减少编译时间.
以下摘自head first Python一书:
解释器第一次执行代码时,它会读入代码,并转换为一种中间字节码格式,最终所要执行的就是这些字节码(这种思想与Java JVM的工作原理很类似:利用Java技术编译代码时,java代码会转换为一个类文件)。
Python解释器非常聪明,下一次模块时会跳过这个转换阶段,因为它能确定原来的模块代码何时有变化。如果你的模块代码没有变,就不会发生任何转换,相应的就会执行“编译”版本的代码。如果代码确实发生变化,
则会发生转换(创建一个新的.pyc文件)。这样做的好处是让程序运行的更快。
二、模块
模块就是一个包含python代码的文本文件。对模块的主要需求就是要求文件名以.py结尾。
比如我在一个名为modtest.py的文件里面定义了一个叫做func1的函数,我可以在同一个目录下再新建一个python文件,然后调用func1这个函数。如何调用如下
import modtest #导入这个模块,不需要加py后缀
modtest.func1() #调用函数,前面一定要加modtest.,不然直接调用func1会找不到此函数
解释:主python程序中(以及IDLE,shell中)的代码与一个名为__main__(两边各两个下划线)的命名空间有关。将代码放在其单独的模块中时,
python会自动创建一个与模块同名的命名空间。所以上面模块中的代码与一个名叫modtest的命名空间有关,就如同姓氏一样,可能你的主python程序中
也有叫做func1的,或者其它模块中也有叫func1的,如果没有前面的命名空间,就不知道调用谁,或者找不到。
以上也可以 from modtest import func1
调用func1直接可以func1()使用,前提是当前的python文件中没有叫func1()的函数。#当时测试过,如果执行func1()在新定义func1()的前面调用,那么会使用你导入的,如果在新定义的func()后面调用,值就行新定义的func1(),可能新定义func1把导入的替换掉了
补充:PyPI,Python包索引(python package index),第三方模块的集中存储库
import 模块名
现在当前文件路径下找模块名,再在python的环境变量里面找
使用import sys
sys.path可以获得python的环境变量
安装第三方模块,默认会安装在$python3.5\Lib\site-packages目录里
在win上用pip命令安装报错:unable to create process using ''''
百度了下:python -m pip install 模块文件
关于模块,可以参考:http://www.cnblogs.com/wupeiqi/articles/4963027.html
三、字符编码与转码(copy alex的)
详细文章:
http://www.cnblogs.com/yuanchenqi/articles/5956943.html
http://www.diveintopython3.net/strings.html
需知:
1.在python2默认编码是ASCII, python3里默认是unicode
2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是现在最常用的unicode版本, 不过在文件里存的还是utf-8,因为utf8省空间
3.在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string
上图仅适用于py2
1 #-*-coding:utf-8-*- 2 __author__ = 'Alex Li' 3 4 import sys 5 print(sys.getdefaultencoding()) 6 7 8 msg = "我爱北京天安门" 9 msg_gb2312 = msg.decode("utf-8").encode("gb2312") 10 gb2312_to_gbk = msg_gb2312.decode("gbk").encode("gbk") 11 12 print(msg) 13 print(msg_gb2312) 14 print(gb2312_to_gbk) 15 16 in python2
#-*-coding:gb2312 -*- #这个也可以去掉 __author__ = 'Alex Li' import sys print(sys.getdefaultencoding()) msg = "我爱北京天安门" #msg_gb2312 = msg.decode("utf-8").encode("gb2312") msg_gb2312 = msg.encode("gb2312") #默认就是unicode,不用再decode,喜大普奔 gb2312_to_unicode = msg_gb2312.decode("gb2312") gb2312_to_utf8 = msg_gb2312.decode("gb2312").encode("utf-8") print(msg) print(msg_gb2312) print(gb2312_to_unicode) print(gb2312_to_utf8) in python3
四,列表
1,列表中允许存在相同的元素
可以用.count("name")去查看你
如:
list1 = [1,2,3,4,1,2,5,]
print(list1)
print(list1.count(2))
输出:
2,copy
2.1列表1 = 列表(因为我犯过这个错误,列表中不要些这种)
names = ['cui','wang','luo','zhang','xu']
print(names)
names_1 = names
print(names_1)
names[1] = 'zhao'
print(names)
print(names_1)
print(id(names))
print(id(names_1))
输出为:
['cui', 'wang', 'luo', 'zhang', 'xu'] ['cui', 'wang', 'luo', 'zhang', 'xu'] ['cui', 'zhao', 'luo', 'zhang', 'xu'] ['cui', 'zhao', 'luo', 'zhang', 'xu']
11928968
11928968
可以看到如果列表采用c = a, a= b,b = c,这种a,b互换值是不行的,列表1 =列表2 仅仅只是复制了对对象的引用,即 names 和 names_1 指向的是同一个对象,所以如果改变了该对象的元素的话,则两个表所指向的对象都会改变,因为实际上就是同一个对象。可以由id(names)和id(names_1)看出两者指向的对象在内存中的地址是相同的,即是同一个对象
补充一下:列表2 = 列表1*n,将列表1里面的元素翻n倍,列表2与列表1为相互独立的列表
>>> names = ['cui','hu','zhang','wang','luo'] >>> names_copy = names * 3 >>> names_copy ['cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo'] >>> print(id(names),id(names_copy)) 56032904 55907784
2.2 浅copy
names = ['cui','wang','luo',['zou',29],'zhang','xu'] print(names) names_copy = names.copy() names[0] = 'CUI' #更改names列表里的第一个值 names[3][0] = 'ZOU min' #更改names列表里第三个列表里的第一个值 print(names) print(names_copy)
['cui', 'wang', 'luo', ['zou', 29], 'zhang', 'xu'] ['CUI', 'wang', 'luo', ['ZOU min', 29], 'zhang', 'xu'] ['cui', 'wang', 'luo', ['ZOU min', 29], 'zhang', 'xu']
浅copy是最常用的copy,只会copy列表第一层的对象,列表第一层改动的时候,不会影响copy的列表,但是第二层改动便会影响,因为这个例子中的子列表
令有3种实现方式:
import copy names = ['cui','wang','luo',['zou',29],'zhang','xu'] print(names) names_copy = copy.copy(names)
######################
names_copy = list(names)
##########################
names_copy = names[:]
2.3 深copy deepcopy(完全copy,基本不用,如果一个大表再完全copy一份,相当于占用两个内存空间)
1 import copy 2 names = ['cui','wang','luo',['zou',29],'zhang','xu'] 3 print(names) 4 names_copy = copy.deepcopy(names) 5 names[0] = 'CUI' #更改names列表里的第一个值 6 names[3][0] = 'ZOU min' #更改names列表里第三个列表里的第一个值 7 print(names) 8 print(names_copy)
print(id(names),id(names_copy))
输出
['cui', 'wang', 'luo', ['zou', 29], 'zhang', 'xu'] ['CUI', 'wang', 'luo', ['ZOU min', 29], 'zhang', 'xu'] ['cui', 'wang', 'luo', ['zou', 29], 'zhang', 'xu']
14440968 14441480
看出,无论names如何改动,都不影响names_copy,反之亦然,因为两者指定的是完全不同的内存地址
3,切片
列表元素的下表是从左到右是从0,1,2。。。。。,从右到左是-1,-2,-3
切片的原则是包头不包尾如names[1:-1]指选择第2个元素(下标为1)到倒数第2个(倒数第一个前面那一个)
names ['cui', 'wang', 'luo', 'zhang', 'xu'] names[-2:-1] ['zhang'] names[0:2] ['cui', 'wang'] names[0:] ['cui', 'wang', 'luo', 'zhang', 'xu'] names[:-2] ['cui', 'wang', 'luo'] names[:] ['cui', 'wang', 'luo', 'zhang', 'xu']
下标0是可以省略的,names[:]表示全部,names[-3:]表示倒数3个
4,追加
names.append('NEW') names ['cui', 'wang', 'luo', 'zhang', 'xu', 'NEW']
5,插入
names = ['cui','wang','luo','zhang','xu'] names.insert(1,'charu1') names.insert(-1,'end') #在最后元素的前面插入'end' print(names)
最后面插入可以用上面的追加
6,修改
names[-2] = 'haha'
将倒数第二个元素修改为'haha'
7,删除
del names[2] #删除第3个元素
del names[3:5] #删除列表中第4个到第5个元素
del names #将列表nanmes整个删除,这样print(names)会报没有定义变量names
或者
names.pop() ##删除最后一个元素
names.pop(2) ###删除第3个元素
或者(删除指定的元素,前提是知道列表中包含这些元素)
['cui', 'wang', 'luo', 'zhang', 'xu']
>>> names.remove('luo')
>>> names
['cui', 'wang', 'zhang', 'xu']
>>>
names = ['cui','wang','luo','zhang','xu',1,2,3,4] for n in ('wang','zhang',1,4): names.remove(n) else: print(names)
8,扩展
names = ['cui','wang','luo','zhang','xu'] age = [1,2,3,5] names.extend(age)
输出:
['cui', 'wang', 'luo', 'zhang', 'xu', 1, 2, 3, 5]
扩展:extend与+,+=的区别(表面看效果一样,都是将后面列表元素全部追加进前面列表中)
>>> names ['cui', 'wang', 'zhang', 'xu'] >>> age [1, 2, 3] >>> names = names + age >>> names ['cui', 'wang', 'zhang', 'xu', 1, 2, 3]
names = ['cui','wang','luo','zhang','xu'] age = [1,2,3] print(id(names),id(age)) names.extend(age) print(id(names)) 输出: 12059912 12040968 12059912
使用extend,names在扩展前后还是指向同一个内存地址
names = ['cui','wang','luo','zhang','xu'] age = [1,2,3] print(id(names),id(age)) names += age print(id(names)) 输出: 14222600 14203656 14222600
使用+=,和extend效果一样
names = ['cui','wang','luo','zhang','xu'] age = [1,2,3] print(id(names),id(age)) names = names + age print(id(names)) 输出: 14157064 14138120 13448072
但是使用+,却是生成一个新的列表
9,统计
1的例子已经包含了,names.count('cui') #统计列表names里面有几个‘cui’
10,排序&翻转(list.sort() list.reverse())
1 >>> names 2 ['cui', 'wang', 'luo', 'zhang', 'xu', 1, 2] 3 >>> names[-1] = '2' 4 >>> names[-2] = '1' 5 >>> names 6 ['cui', 'wang', 'luo', 'zhang', 'xu', '1', '2'] 7 >>> names.sort() 8 >>> names 9 ['1', '2', 'cui', 'luo', 'wang', 'xu', 'zhang'] 10 >>> names.reverse() 11 >>> names 12 ['zhang', 'xu', 'wang', 'luo', 'cui', '2', '1'] 13 >>>
注意:排序前必须同一类型,顺序按照ASCII的顺序
补充:原地排序是指按照你指定的顺序排列数据,然后用排序后的数据替换原来的数据,原来的顺序会丢失。list.sort()
复制排序是指按照你指定的顺序排列数据,然后返回原数据的一个有序副本。原数据的顺序依然保留,只是对一个副本排序。sorted(列表) BIF
>>> a = [1,0,10,7,11,5]
>>> a.sort()
>>> a
[0, 1, 5, 7, 10, 11]
>>>
>>> a = [1,0,10,7,11,5]
>>> b = sorted(a)
>>> a
[1, 0, 10, 7, 11, 5]
>>> b
[0, 1, 5, 7, 10, 11]
>>>
另外:向sort()或sorted()传入参数reverse = true可以按照降序排列数据
11,获取列表元素的下标(list.index)
1 ['zhang', 'xu', 'wang', 'luo', 'cui', '2', '1'] 2 >>> names.index('wang') 3 2 4 >>>
12,清空列表(list.clear())
>>> names ['cui', 'hu', 'zhang', 'wang', 'luo'] >>> names.clear() >>> names [] >>>
13,列表去重(set(list))
>>> names_copy ['cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo'] >>> set(names_copy) {'hu', 'luo', 'cui', 'wang', 'zhang'} >>>
14,如何查找一个列表中的重复元素(刚琢磨的,后续改进)
如果 len(names) = len(set(names)),说明列表不包含重复元素,len(list),会显示列表的长度,也就是有多少个元素
names = ['cui','luo','wang','xupin','xupin','hu',1,2,1,2,1] if len(names) != len(set(names)): names_tmp = [] for n in range(len(names)): if names[n] not in names_tmp: names_tmp.append(names[n]) else: print('重复元素:',names[n],'索引位置为:',n) print('重复元素:',names[n],'索引位置为:',names.index(names[n])) else: print(names_tmp) else: print('列表不包含重复元素') 输出为: 重复元素: xup 索引位置为: 4 重复元素: xup 索引位置为: 3 重复元素: 1 索引位置为: 8 重复元素: 1 索引位置为: 6 重复元素: 2 索引位置为: 9 重复元素: 2 索引位置为: 7 重复元素: 1 索引位置为: 10 重复元素: 1 索引位置为: 6 ['cui', 'luos', 'wang', 'xup', 'hu', 1, 2]
五,元组
元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表。
它只有2个方法,一个是count,一个是index。
>>> age = (1,3,5,7,7) >>> age (1, 3, 5, 7, 7) >>> age.count(7) 2 >>> age.index(7) 3
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· 盘点!HelloGitHub 年度热门开源项目
· 某Websocket反爬逆向分析+请求加解密+还原html
· DeepSeek V3 两周使用总结
· 02现代计算机视觉入门之:什么是视频
· 回顾我的软件开发经历:我与代码生成器的涅槃之路