Python自学-Day2 自记笔记
本日内容
一、模块初识
二、什么是pyc
三、数据类型初识
四、三元运算
五、数据运算
六、进制
七、列表与元祖
八、字典
九、字符串的操作
十、三级菜单
一、模块初识
getpass模块在Day-1中已经使用过
模块分两种,标准库与第三方库,标准库不需要安装,直接导入就可以使用,第三方库需要下载安装,比如jongo
初识下两个标准库
1.sys模块
import sys
print(sys.path) #打印环境变量
执行后会输出一些路径,这里就显示了python的标准库与第三方库存放模块的路径
1 C:\Users\username\AppData\Local\Programs\Python\Python36\lib 2 D:\Study_Python\venv\lib\site-packages
一般 lib存放系统自带的模块,site-packages存放第三方模块;
print(sys.argv)
会输出当前python文件的相对路径,以列表的形式出现
2.os模块
在python中调用shell,在系统中创建文件,做操作,这些就是os模块的作用,先学这两个作用
1 import os 2 cmd_res = os.system("dir") #执行命令,不保存结果 3 print("---->",cmd_res) 4 5 cmd_res2 = os.popen("dir").read() #执行命令,并用read在内存里把结果取出 6 print("---->",cmd_res2) 7 8 cmd_res3 = os.mkdir("new_dir") #在当前路径创建一个新的目录
3.第三方库
自己写的模块要记得放在当前路径或者site-packages下
二、什么是pyc
在刚才调用了自己做的第三方库之后,出现了pycache,里面有pyc文件
1 D:\Study_Python\Day-2\__pycache__\passwd.cpython-36.pyc
1. Python是一门解释型语言?
我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在。如果是解释型语言,那么生成的*.pyc文件是什么呢?c应该是compiled的缩写才对啊!
为了防止其他学习Python的人也被这句话误解,那么我们就在文中来澄清下这个问题,并且把一些基础概念给理清。
2. 解释型语言和编译型语言
计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程。这个过程分成两类,第一种是编译,第二种是解释。
编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是C语言。
解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是Ruby。
通过以上的例子,我们可以来总结一下解释型语言和编译型语言的优缺点,因为编译型语言在程序运行之前就已经对程序做出了“翻译”,所以在运行时就少掉了“翻译”的过程,所以效率比较高。但是我们也不能一概而论,一些解释型语言也可以通过解释器的优化来在对程序做出翻译时对整个程序做出优化,从而在效率上超过编译型语言。
此外,随着Java等基于虚拟机的语言的兴起,我们又不能把语言纯粹地分成解释型和编译型这两种。
用Java来举例,Java首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件。所以我们说Java是一种先编译后解释的语言。
3. Python到底是什么
其实Python和Java/C#一样,也是一门基于虚拟机的语言,我们先来从表面上简单地了解一下Python程序的运行过程吧。
当我们在命令行中输入python hello.py时,其实是激活了Python的“解释器”,告诉“解释器”:你要开始工作了。可是在“解释”之前,其实执行的第一项工作和Java一样,是编译。
熟悉Java的同学可以想一下我们在命令行中如何执行一个Java的程序:
javac hello.java
java hello
只是我们在用Eclipse之类的IDE时,将这两部给融合成了一部而已。其实Python也一样,当我们执行python hello.py时,他也一样执行了这么一个过程,所以我们应该这样来描述Python,Python是一门先编译后解释的语言。
4. 简述Python的运行过程
在说这个问题之前,我们先来说两个概念,PyCodeObject和pyc文件。
我们在硬盘上看到的pyc自然不必多说,而其实PyCodeObject则是Python编译器真正编译成的结果。我们先简单知道就可以了,继续向下看。
当python程序运行时,编译的结果则是保存在位于内存中的PyCodeObject中,当Python程序运行结束时,Python解释器则将PyCodeObject写回到pyc文件中。
当python程序第二次运行时,首先程序会在硬盘中寻找pyc文件,如果找到,则直接载入,否则就重复上面的过程。
所以我们应该这样来定位PyCodeObject和pyc文件,我们说pyc文件其实是PyCodeObject的一种持久化保存方式。
三、数据类型初识
数字
2 是一个整数的例子。
长整数 不过是大一些的整数。
3.23和52.3E-4是浮点数的例子。E标记表示10的幂。在这里,52.3E-4表示52.3 * 10-4。
(-5+4j)和(2.3-4.6j)是复数的例子,其中-5,4为实数,j为虚数,数学中表示复数是什么?。
int(整型)
在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1,即-2147483648~2147483647
在64位系统上,整数的位数为64位,取值范围为-2**63~2**63-1,即-9223372036854775808~9223372036854775807
long(长整型)
跟C语言不同,Python的长整数没有指定位宽,即:Python没有限制长整数数值的大小,但实际上由于机器内存有限,我们使用的长整数数值不可能无限大。
注意,自从Python2.2起,如果整数发生溢出,Python会自动将整数数据转换为长整数,所以如今在长整数数据后面不加字母L也不会导致严重后果了。
python3无论存多大都是整形,没有长整型了,只有int,没有long
float(浮点型)
先扫盲 http://www.cnblogs.com/alex3714/articles/5895848.html
浮点数用来处理实数,即带有小数的数字。类似于C语言中的double类型,占8个字节(64位),其中52位表示底,11位表示指数,剩下的一位表示符号。
complex(复数)
复数由实数部分和虚数部分组成,一般形式为x+yj,其中的x是复数的实数部分,y是复数的虚数部分,这里的x和y都是实数。
注:Python中存在小数字池:-5 ~ 257
2、布尔值
真或假
1 或 0
3、字符串
"hello world"
万恶的字符串拼接:
python中的字符串在C语言中体现为是一个字符数组,每次创建字符串时候需要在内存中开辟一块连续的空,并且一旦需要修改字符串的话,就需要再次开辟空间,万恶的+号每出现一次就会在内从中重新开辟一块空间。
4.byte类型与str相互转换
1 string----------------->bytes(\x01\x06\xfc...) 2 encode 3 <----------------- 4 decode
1 # Auther: Tank Jarvis 2 msg = "我爱北京" 3 print(msg) 4 5 print(msg.encode(encoding="utf-8")) 6 print(msg.encode(encoding="utf-8").decode()) 7 8 Result: 9 我爱北京 10 b'\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\xe4\xba\xac' 11 我爱北京 12 13 Process finished with exit code 0
四、三元运算
1 a,b,c = 1,3,5 2 3 d = a if a > b else c 4 print(d) 5 d = a if a < b else c 6 print(d)
d的值可能是1,也可能是5,看设置的条件而定,这就是三元运算
五、数据运算
算数运算:
比较运算:
赋值运算:
逻辑运算:
成员运算:
身份运算:
位运算:
1 #!/usr/bin/python 2 3 a = 60 # 60 = 0011 1100 4 b = 13 # 13 = 0000 1101 5 c = 0 6 7 c = a & b; # 12 = 0000 1100 8 print "Line 1 - Value of c is ", c 9 10 c = a | b; # 61 = 0011 1101 11 print "Line 2 - Value of c is ", c 12 13 c = a ^ b; # 49 = 0011 0001 #相同为0,不同为1 14 print "Line 3 - Value of c is ", c 15 16 c = ~a; # -61 = 1100 0011 17 print "Line 4 - Value of c is ", c 18 19 c = a << 2; # 240 = 1111 0000 20 print "Line 5 - Value of c is ", c 21 22 c = a >> 2; # 15 = 0000 1111 23 print "Line 6 - Value of c is ", c
*按位取反运算规则(按位取反再加1) 详解http://blog.csdn.net/wenxinwukui234/article/details/42119265
运算符优先级:
六、进制
- 二进制,01
- 八进制,01234567
- 十进制,0123456789
- 十六进制,0123456789ABCDEF 二进制到16进制转换http://jingyan.baidu.com/album/47a29f24292608c0142399cb.html?picindex=1
计算机内存地址和为什么用16进制?
为什么用16进制
1、计算机硬件是0101二进制的,16进制刚好是2的倍数,更容易表达一个命令或者数据。十六进制更简短,因为换算的时候一位16进制数可以顶4位2进制数,也就是一个字节(8位进制可以用两个16进制表示)
2、最早规定ASCII字符集采用的就是8bit(后期扩展了,但是基础单位还是8bit),8bit用2个16进制直接就能表达出来,不管阅读还是存储都比其他进制要方便
3、计算机中CPU运算也是遵照ASCII字符集,以16、32、64的这样的方式在发展,因此数据交换的时候16进制也显得更好
4、为了统一规范,CPU、内存、硬盘我们看到都是采用的16进制计算16进制用在哪里
1、网络编程,数据交换的时候需要对字节进行解析都是一个byte一个byte的处理,1个byte可以用0xFF两个16进制来表达。通过网络抓包,可以看到数据是通过16进制传输的。
2、数据存储,存储到硬件中是0101的方式,存储到系统中的表达方式都是byte方式3、一些常用值的定义,比如:我们经常用到的html中color表达,就是用的16进制方式,4个16进制位可以表达好几百万的颜色信息。
七、列表与元祖
一般我们要存数据用变量存,一个是整数,一个是字符串
如果要存100人的名字呢?
一个人名一个变量吗?
太LOW了,如果你想存很多的字符串信息,这里就引出了列表
1 # Auther: Tank Jarvis 2 names = ["zhangsan","lisi","wangwu","maliu"] 3 print(names[0]) #取第1个值 4 print(names[1:3]) #取第2个和第3个的值,起始位置包括,结束为止往后错一位 5 print(names[0:3]) #也叫切片 6 print(names[-1]) #倒着数是从-1开始 7 print(names[-2:]) #取值的顺序都是从左往右 8 print(names[:2]) #开头和结尾可省略 9 names.append("Meiguoduizhang") #追加在最后 10 names.insert(1,"Heiguafu") #插入到哪个位置就写几 11 names.insert(3,"Zhizhuxia") #插入到哪个位置就写几 12 print(names) #插入只能一个一个来 13 names[2] = "Ironman" #更改 14 15 names.remove("Meiguoduizhang") #按照值删除 16 del names[-1] #按照下标删除 17 names.pop() #没输入下标,pop就是删除最后一个值 18 19 #根据值找下标:index 20 print(names.index("Heiguafu")) 21 print(names[names.index("Heiguafu")]) 22 23 #值出现重复的时候,计数重复数量 24 names.append("Ironman") 25 print(names.count("Ironman")) 26 27 #反转 28 names.reverse() 29 print(names) 30 31 #排序:先特殊字符,再数字,再大写,再小写,遵循ACSII码排序规则 32 names.sort() 33 print(names) 34 35 #扩展吸收其他列表 36 names2 = [1,2,3,4] 37 names.extend(names2) 38 print(names) 39 print(names2) 40 41 #删掉names2这个变量 42 del names2 43 print(names2) 44 45 #清空列表 46 names.clear() 47 print(names)
copy单独讲一下:注意深层次的列表copy的是内存指针,值会跟着变,这样也叫浅copy
1 # Auther: Tank Jarvis 2 #COPY的用法 3 names = ["zhangsan","lisi","wangwu","maliu"] 4 5 names2 = names.copy() 6 print(names,names2) 7 8 names[1] = "李四" 9 print(names,names2) 10 11 names.insert(3,[1,2,"tank"]) 12 names3 = names.copy() 13 print(names,names3) 14 15 names[3][0] = "Jarvis" 16 print(names,names3) 17 #第二层列表被复制后,源names改第二层列表也会使得names3的第二层 18 #列表也会跟着更改,因为下一层列表copy的是内存指针,会根据内存的值改变
怎么做到深copy 导入copy模块,使用copy.deepdopy()
1 # Auther: Tank Jarvis 2 3 names = ["zhangsan","lisi","wangwu","maliu"] 4 5 #深copy 6 import copy 7 names.append([1,2,"tank"]) 8 names2 = copy.deepcopy(names) 9 print(names,names2) 10 11 names[-1][0] = "Jarvis" 12 print(names,names2)
循环和步长切片
1 # Auther: Tank Jarvis 2 3 names = ["zhangsan","lisi","wangwu","maliu"] 4 #循环 5 for i in names: 6 print(i) 7 8 #跳着切片 步长切片 9 print(names[0:-1:2]) 10 print(names[::2])
列表个字典在开发中最最常用的数据类型
元祖就是列表,但元祖是只读的,只能切片,只能查,不可变写法不是[],而是(),小括号
只有两个方法:count,index
1 # Auther: Tank Jarvis 2 names = ("zhangsan","lisi","wangwu","maliu","tank") 3 print(names.count("zhangsan")) #计数 4 print(names.index("maliu")) #根据值查下标
做个练习
程序:购物车程序
需求:
- 启动程序后,让用户输入工资,然后打印商品列表
- 允许用户根据商品编号购买商品
- 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒
- 可随时退出,退出时,打印已购买商品和余额
1 # Auther: Tank Jarvis 2 salary = input("Please input your balance: ") 3 product_list = [ 4 ("iphone",10000), 5 ("mac",12000), 6 ("iwatch",5800), 7 ("coofee",66), 8 ("bike",800) 9 ] 10 buy_list = [] 11 if salary.isdigit(): 12 salary = int(salary) 13 while True: 14 # for iterm in product_list: 15 # print(product_list.index(iterm),iterm) 16 for index,item in enumerate(product_list): 17 print(index,item) 18 user_choice = input("Please choose the num of product :" ) 19 if user_choice.isdigit(): 20 user_choice = int(user_choice) 21 if user_choice >= 0 and user_choice < len(product_list): 22 p_item = product_list[user_choice] 23 if p_item[1] <= salary: 24 buy_list.append(p_item) 25 salary -= p_item[1] 26 print("Added %s into shopping cart, your current balance is %s" %(p_item,salary)) 27 else: 28 print("Your current balance is not enough, it is only %s" % (salary)) 29 else: 30 print("your choice is not valid.") 31 elif user_choice == "q": 32 print("---------shopping list---------") 33 for p in buy_list: 34 print(p) 35 print("Your current salary is ",salary) 36 exit() 37 else: 38 print("invalid option")
八、字典
1 # Auther: Tank Jarvis 2 info = { 3 'stu1101' : "Wu Tenglan", 4 'stu1102': "Longze Luola", 5 'stu1103': "Cang jingkong", 6 } 7 8 print(info)
print info后会发现字典的顺序是无序的,因为字典没有下标,而是key-value的形式,那怎么取一个key对应的值呢?增删改查怎么表达?
1 2 print(info["stu1101"]) #查 3 print(info.get("stu1101")) #不会报错的查找 4 print("stu1104" in info) #如果不在就创建一个,如果在就取出来 5 info["stu1101"] = "武藤兰" #改 6 print(info["stu1101"]) 7 8 info["stu1104"] = "XiaozeMaria" #增 9 print(info) 10 11 del info["stu1101"] #删 12 info.pop("stu1104") 13 info.popitem() #随机删除一个 14 print(info) 15 16 #打印所有的values 17 print(info.values()) 18 #打印所有的key 19 print(info.keys())
1 daily_catalog = { 2 "Eu":{ 3 "www.youtube.com":["Free", "biggest"], 4 "www.google.com.cn":["Best","Search"] 5 }, 6 "Asia":{ 7 "www.youku.com":["Local","Free"], 8 "www.baidu.com":["Most","Rubbish"] 9 }, 10 "China":{ 11 "www.bilibi.com":["Zhibo","Real-time"], 12 "www.douyu.com":["Biggest","Zhibo"] 13 } 14 } 15 16 print(daily_catalog) 17 18 daily_catalog["China"]["www.douyu.com"][1] = "HaHa" #改 19 print(daily_catalog) 20 21 #赋值的key如果存在,就不会更改,如果不存在就创建 22 daily_catalog.setdefault("Amrica",{"www.facebook.com":["Friend","Social"]}) 23 print(daily_catalog) 24 daily_catalog.setdefault("China",{"www.facebook.com":["Friend","Social"]}) 25 print(daily_catalog)
其他姿势:
1 info = { 2 'stu1101' : "Wu Tenglan", 3 'stu1102': "Longze Luola", 4 'stu1103': "Cang jingkong" 5 } 6 7 b = { 8 "stu1101" : "Alex", 9 1:3, 10 2:4 11 } 12 info.update(b) 13 #把两个字典合并,有交叉就更新,无交叉就写入 14 print(info) 15 print(b) 16 #把字典转换成列表 17 print(info.items()) 18 #初始化一个新的字典 19 c = dict.fromkeys([7,8,9],[1,{"name":"Tank"},444]) 20 print(c) 21 #为什么改一个key,后边全改了?我们认为是创建了3份独立的数据,其实不是 22 #而是3个key共享一个内存地址,所以记住用这个fromkeys有一个坑,在多级的时候 23 c[7][1]["name"] = "Jarvis" 24 print(c)
字典的for循环:
1 info = { 2 'stu1101': "Wu Tenglan", 3 'stu1102': "Longze Luola", 4 'stu1103': "Cang jingkong" 5 } 6 #更高效 7 for i in info: 8 print(i,info[i]) 9 #items是先把字典变成列表,过程多的时候机器就崩了,忘记这个吧 10 for k,v in info.items(): 11 print(k,v)
九、字符串的操作
1 # Auther: Tank Jarvis 2 3 name = "my name is tank" 4 5 print(name.capitalize()) #首字母大写 6 print(name.count("a")) #计数 7 print(name.center(50,"-")) #优化显示 8 print(name.encode()) #把字符串转成二进制 9 print(name.endswith("ank")) #判断一个字符串以什么结尾 10 print(name.expandtabs()) #转换tab键成空格 11 print(name.find("tank")) #字符串切片 12 print(name.format()) #匹配赋值 13 print(name.isalnum()) #判断是否为阿拉伯英文与数字,其他字符会返回False 14 print(name.isalpha()) #判断是否为纯英文 15 print(name.isdecimal()) #判断是否为十进制 16 print(name.isdigit()) #判断是否为整数,常用 17 print(name.isidentifier()) #判断是否为合法的标识符,是不是一个合法的变量名 18 print(name.islower()) #判断是不是小写 19 print(name.isnumeric()) #判断是不是一个整数 20 print(name.isspace()) #判断是不是空格 21 print(name.istitle()) #判断每个单词的首字母是否大写 22 print(name.isupper()) #判断是不是全大写 23 print("+".join(["1","2","3"])) #把一个设定的字符插入到列表中的每个间隙形成一个字符串 24 print(name.ljust(50,"*")) #总长50,在后面用*补位 25 print(name.rjust(50,"-")) #总长50,在后面用-补位 26 print(name.lower()) #把大写变小写 27 print(name.upper()) #把小写变大写 28 print(name.lstrip()) #strip去掉空格和回车 l去除左边 r去除右边 29 print(name.rstrip()) 30 print(name.strip()) 31 p = str.maketrans("abcdef","123456") #maketrans可以做对应的规则替换 32 print("hello, my name is alex".translate(p)) 33 print(name.replace("m","123",1))#把变量里的字母替换掉 34 print(name.rfind("m")) #匹配最右边的下标并返回 35 print(name.split("n")) #把字符串按照空格分成列表,也可以按照其他数据分 36 print(name.splitlines()) #把字符串按照 行 分成列表 37 print('Alex Li 123'.swapcase()) #英文字母大写变小写,小写变大写 38 print(name.title()) #每个英文字母都大写
十、三级菜单
做一个三级菜单,可以任意退出,一层一层选择进入,并可以一层一层返回
1 # Auther: Tank Jarvis 2 3 data = { 4 "北京":{ 5 "朝阳":{ 6 "医院":["安贞医院","安贞二院"], 7 "社区":["安贞里","安贞里三区"] 8 }, 9 "海淀":{ 10 "医院":"西青医院", 11 "社区":"生态技术园" 12 } 13 }, 14 "哈尔滨":{ 15 "道外":{ 16 "医院":"安贞医院", 17 "社区":"翌景嘉园" 18 }, 19 "道里":{ 20 "医院":"道里医院", 21 "社区":"幸福家园" 22 } 23 }, 24 "绥化":{ 25 "兰西":{ 26 "医院":"兰西医院", 27 "社区":"祥和丽苑" 28 }, 29 "青冈":{ 30 "医院":"青冈医院", 31 "社区":"青冈家园" 32 } 33 } 34 } 35 36 exit_flag = False #标志位 37 38 while not exit_flag: 39 for i in data: 40 print(i) 41 choice1 = input("选择1级菜单>>:") 42 if choice1 in data: 43 while not exit_flag: 44 for i2 in data[choice1]: 45 print("\t",i2) 46 choice2 = input("选择2级菜单>>:") 47 if choice2 in data[choice1]: 48 while not exit_flag: 49 for i3 in data[choice1][choice2]: 50 print("\t\t",i3) 51 choice3 = input("选择3级菜单>>:") 52 if choice3 in data[choice1][choice2]: 53 for i4 in data[choice1][choice2][choice3]: 54 print("\t\t\t",i4) 55 choice4 = input("最后一层,按b返回>>:") 56 if choice4 == "b": 57 pass 58 elif choice4 == "q": 59 exit_flag = True 60 if choice3 == "b": 61 break 62 elif choice3 == "q": 63 exit_flag = True 64 if choice2 == "b": 65 break 66 elif choice2 == "q": 67 exit_flag = True 68 elif choice1 == "q": 69 exit_flag = True