Python 代码执行流程:
- 编译 --> 执行
- 源代码 --> 字节码 --> 机器码 --> CPU执行
python 先将自己的源代码,编译成Python 字节码,不同语言的字节码,只有对应的编译器可以识别,运行时再将字节码转换成机器码在执行,经过了现两个转换的步骤,所以比 C 语言要慢一个量级。
Python 的几种实现:
python 作为一种编程语言,它有多种实现。这里的实现指的是符合Python语言规范的Python解释程序以及标准库等。这些实现虽然实现的是同一种语言,但是彼此之间,特别是与CPython之间还是有些差别的。
1、CPython:Python的官方版本,使用C语言实现,使用最为广泛,新的语言特性一般也最先出现在这里。
C 语言实现的 python --> C 解释器 --> .pyc(字节码) --> 机器码 --> CPU执行
2、Jpython:这是Python的Java实现,相比于CPython,它与Java语言之间的互操作性要远远高于CPython和C语言之间的互操作性。
java 实现的 python --> java 解释器 --> java字节码 --> 机器码 --> CPU执行
3、Python for .NET:它实质上是CPython实现的.NET托管版本,它与.NET库和程序代码有很好的互操作性。
4、IronPython:不同于Python for .NET,它是Python的C#实现,并且它将Python代码编译成C#中间代码(与Jython类似),然后运行,它与.NET语言的互操作性也非常好。
5、PyPy:Python的Python实现版本,原理是这样的,PyPy运行在CPython(或者其它实现)之上,用户程序运行在PyPy之上。它的一个目标是成为Python语言自身的试验场,因为可以很容易地修改PyPy解释器的实现(因为它是使用Python写的)。
python 源代码 --> py解释器 --> 字节码、机器码(编译过程中就已经生成机器码) --> CPU 执行
Python 执行过程:
- 语法分析 (检测你的语法是否有问题)
- 词法分析( 说明代码写的没问题)
- 编译代码(遇到函数与类解释的方式不同,生成字节码)
- 执行(转换成机器码)
Python 运行后,原目录下会生成 .pyc(Python 编译后生成的专有字节码文件) 可用工具反解。
Python 执行时会优先找 .pyc 文件,当没有 .pyc 会先执行 py 生成字节码,如果 py 文件被修改过,与 .pyc 文件中的内容不符,Python 会重新编译生成 .pyc 并替换。
字符集与字符编码:
1.字符集:
- 字符是各种文字和符号的总称,包括各个国家文字、标点符号、图形符号、数字等。字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同。
- 常见字符集有:ASCII字符集、ISO 8859字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。
- 计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。
2.编码(encoding):
- 编码(encoding)与字符集不同。字符集只是字符的集合,不一定适合作网络传送、处理,有时须经编码(encode)后才能应用。
- 如Unicode可依不同需要以 UTF-8、UTF-16、UTF-32等方式编码。
- 字符编码就是以二进制的数字来对应字符集中的字符。
使用哪些字符。也就是说哪些汉字,字母和符号会被收入标准中。所包含“字符”的集合就叫做“字符集”。
规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“编码”。
常用字符编码:
ASCII:
- (American Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以勉强显示其他西欧语言。它是现今最通用的单字节编码系统(但是有被UniCode追上的迹象)
- ASCII 采用 7 位或 8 位 二进制数组合来表示 128 或 256 种可能出现的字符,在计算机没有大规模发展时,128位足以表示英文字符与数字,但后期计算机经过广泛发展,在世界的各个角落流行起来,采取传统的 8 位二进制数最多只能表示 256 种字符变化,对于纯英文来说足够,但是并不适于其它国家的语言,,已经不能满足其它国家对字符的表示需求。
Unicode:
万国码,它至少采用 2byte 来表示字符,表示范围是世界上各个国家的字符,范围很大,比如,汉字“严”的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。
这就会出现两个严重的问题:
如何才能区别unicode和ascii?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0来填充,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。
它们造成的结果是:
- 出现了unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示unicode。
- unicode在很长一段时间内无法推广,直到互联网的出现。
Unicode:
互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,但只有 UTF-8 被广泛使用,注意:UTF-8是Unicode的实现方式之一。
- UTF-8最大的一个特点,它是一种变长的编码方式。它可以使用1~4个字节表示一个字符,根据不同的字符而变化字节长度,避免了 Unicode 中浪费磁盘空间的问题。
GBK:
- 专属用来表示中文的一种字符编码。
Python 编码:
- python 2.x 默认采用 Unicode 编码格式,让人非常头疼的问题就是编码问题。
- 如果想让 Python 支持中文字符需要在文件顶部声明编码格式为:utf-8
-
#-*- coding:utf-8 -*-
Unicode 与 GBK 之间需要互相转换,需要先解码(encode)成 Unicode 在编码(decode)成对应的编码。
-
- 如果想让 Python 支持中文字符需要在文件顶部声明编码格式为:utf-8
- python 3.x 默认采用 UTF-8 编码格式,原生支持中文。
传入参数:
import sys
print sys.argv # 用于接收 Python 解释器传入的参数,argv 输出类型为列表
# sys 是 python 的标准模块,Python 解释器相关的功能都封装在 sys 模块中。
对于 Python 一切事物皆对象,对象基于类创建,类中有很多功能,都会被对象所继承。
print (type (tu)) # type 返回对象属于哪个类
print (dir(tu)) # dir 返回类中有哪些(成员) 方法
字符串格式化:
1、万恶的 + 号:
Python 是用 C 语言开发而来,在 C 语言中没有字符串的概念,C 只有字符数组。
str_1 = 'alex'
str_2 = 'Jay'
str_1在内存中存储为: ['a','l','e','x']
内存中的操作:
C 在内存中申请一段连续的空间 A0 用来存储 alex 这个字符数组,此时其它程序需要在内存空间来存储数据继续向内存申请 A0 后的空间 B1 ,当 str_1 + str_2 时,在 C 内部,会在内存中重新申请一段空间D1用来存储 ['a','l','e','x','J','a','y'] ,此时原有空间 A1 中存储的内容,没有任何意义,但并不会被立即释放掉,需要靠C 语言自己的内存回收机制。
当 + 号用的较多时,就浪费了很多内存空间。 所以在字符串拼接时,尽量不用 + 号两拼接两个字符串。
2、% 号连接字符串:
name = "Jay"
age = 100
sex = "boy"
print ("My name is %s age %d sex %s !" %(name,age,sex))
字符串操作:
S = "jay"
字符串大小写转换:
S.lower() # 将字符串 S 中内容转换为小写
S.upper() # 将字符串 S 中内容转换为大写
S.swapcase() # 将字符串 S 中内容大小写互转(原本 S 中大写字母转换为小写,原本 S 中小写字母转为大写)
S.capitalize() # 将字符串 S 中内容首字母变大写(不论 S 中原内容大写或小写,将首字母变成大写,其余字母统一转换成小写)
s = "Jay is JAY"
print (s.capitalize())
> Jay is jay
capitalize
S.title() # 将字符串 S 中内容的每个单词首字母变大写(其余字母统一变小写)
s = "Jay is JAY"
print (s.title())
>Jay Is Jay
title
字符串输出对齐:
S.ljust(width,[fillchar]) # 输出 width 个字符,S 中内容左对齐,不足部分用 fillchar(可省略) 填充,默认为空格。
S.rjust(width,[fillchar]) # 输出 width 个字符,S 中内容右对齐,不足部分用 fillchar(可省略) 填充,默认为空格。
S.center(width,[fillchar]) # 输出 width 个字符,S 中内容居中对齐,不足部分用 fillchar(可省略) 填充,默认为空格。
S.zfill(width) # 将 S 变成 width 长,S中内容右对齐,不足部分以 0 填充。
s = "Jay is JAY"
print (s.zfill(100))
> 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Jay is JAY
zfill
字符串的搜索与替换:
S.find(substr, [start, [end]]) # 返回 S 中出现 substr 的第一个字母位置(区分大小写),如 S 中没有指定的 substr 返回 -1,start,end 指定搜索的起始与结束位置(可省)。
S.rfind(substr, [start, [end]]) # 返回 S 中最后出现 substr 的第一个字母位置,其余同 find() 函数。
S.index(substr,[start,[end]]) # 与 find() 相同,区别在于 S 中没有 substr 时,程序中止并返回错误。
S.rindex(substr,[start,[end]]) # 返回 S 中最后出现 substr 的第一个字母位置,其余同 index 函数。
S.strip([chars]) # 将 S 内容中前后 chars 字符全部掉(只能去除字符两侧),chars 默认为空白。
name = " My name is Jay "
print (name.strip())
> My name is Jay
strip()
S.lstrip([chars]) # 只去除左侧出现的内容,其余同上。
S.rstrip([chars]) # 只去除右侧出现的内容,其余同上。
S.count(substr, [start, [end]]) # 计算 substr 在 S 中出现的次数。
S.replace(oldstr,newstr,[count]) # 将 S 中 oldstr 替换为 newstr, count 为替换次数。
s = "Jay is JAY aa"
print (s.replace("a","Q",2))
> JQy is JAY Qa
replace()
S.expandtabs([tabsize]) # 把 S 中的 tab 字符替换为空格,每个 tab 替换为 tabsize 个空格,tabsize 默认值为 8。
S.split([sep, [maxsplit]]) # 以 spe 为分隔符,把 S 分成一个 list。 maxsplit 为分隔次数,默认分割符为空格。
str = "Hello,world,My,name is Jay"
print (str.split(",",2))
> ['Hello', 'world', 'My,name is Jay']
split()
S.rsplit([sep,[maxsplit]]) # 从右侧开始分隔,其余同上。
S.splitlines([keepends]) # 将字符串根据"\n"(换行符)分割成列表。
str = "Hello World\n My name\n is Jay\n !!!"
print (str.splitlines())
> ['Hello World', ' My name', ' is Jay', ' !!!']
S.join(seq) #连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新字符串。
#字符串:
str = "Hello World"
print ("-".join(str))
> H-e-l-l-o- -W-o-r-l-d #列表:
str = ['hello','good','world']
print (":".join(str))
> hello:good:world #元组:
str = ('hello','good','world')
print (":".join(str))
> hello:good:world 字典:
str = {'name':'jay','age':100,'sex':"boy"}
print ("-".join(str))
> name-age-sex # 所有的键
字符串的判断:
S.startswith(prefix[,start[,end]]) # S 中的内容是否以 prefix 开头,返回 True 或 False。
str = "My name is Jay"
print (str.startswith("My"))
> True
startswith()
S.endswith(suffix[,start[,end]]) # S 中的内容是否以 suffix 结尾,返回 True 或 False。
str = "My name is Jay"
print (str.endswith("ay"))
> True
endswith()
len(str) # 返回 str 中内容的长度。
S.isalnum() # S 中内容是否全是字母和数字,并至少有一个字符,返回 True 或 False S内容为空时返回 False,S 内容中有空格时返回 False。
S.isalpha() # S 中内容是否全是字母,并至少有一个字符,返回 True 或 False S内容为空时返回 False,S 内容中有空格时返回 False。
S.isdigit() # S 中内容是否全是数字,并至少有一个字符,返回 True 或 False S内容为空时返回 False,S 内容中有空格时返回 False。
S.isspace() # S 中内容是否全是空白字符,并至少有一个字符,返回 True 或 False S内容为空时返回 False。
S.islower() # S 中内容是否全是小写,并至少有一个字符,返回 True 或 False S内容为空时返回 False,允许 S 中有空格。
S.isupper() # S 中内容是否全是大写,并至少有一个字符,返回 True 或 False S内容为空时返回 False,允许 S 中有空格。
S.istitle() # S 中内容是首字母大写,并至少有一个字符,返回 True 或 False S内容为空时返回 False,允许 S 中有空格。
注意:字符串对象是不可改变的,也就是说在 Python 创建一个字符串后,上面这些函数并不能将字符串中的某一部分改变,使用函数对字符串进行操作后,会返回一个新的字符串,原字符串并没有改变,可以用 S = 函数() 将结果保存下来,或直接用 print () 将结果输出出来。 并且函数中的参数区分大小写。
列表:
- 列表(list) 是 Python 以及其它语言中最常用到的数据结构之一,Python 使用中括号 [] 来解析列表,列表是可被改变的,它是 Python 中使用最频繁的数据类型。
- 有序
- 可变
列表的创建:
列表是Python 中非常非常常见的数据结构,所以Python提供了一种语法糖,将列表的创建方法list()封装为更简单的创建。
li=[1,2,3,4] 等同于 li=list(1,2,3,4)
列表常见操作:
1 li = [] #创建一个空列表
2 li = [1,2,3,4] # 创建一个纯数字列表
3 li = [1,'a',[2,3]] # 创建一个数字、字符串、嵌套列表
4 li = list('hello') # ['h','e','l','l','o'] # 将字符串变成列表
5 li = list(range(4)) # [0,1,2,3] # 取指定范围列表中内容
6 li = '1,2,3,4,5'.split(',') # ['1,','2,','3','4','5'] 将字符串以指定字符分隔成列表
索引:
li = ["a","b",'c',"d",'e','f',"g",'h']
print (li[0])
> a
列表的切片:
li = ["a","b",'c',"d",'e','f',"g",'h'] print (li[1:])
> ['b', 'c', 'd', 'e', 'f', 'g', 'h'] print (li[:3])
> ['a','b','c']
# 输出从 索引 0 至 索引 3 的内容 print (li[1:3])
> ['b','c']
# Python 索引的输出是顾前不顾后的。 print (li[1:100])
> [b",'c',"d",'e','f',"g",'h']
# 输出位置 1 至 最后一个字符,但并不会报错 print (li[:])
>["a","b",'c',"d",'e','f',"g",'h']
# : 显示列表中所有内容
列表的修改:
li = ["a","b",'c',"d",'e','f',"g",'h']
li[1] = "a"
print (li)
> ["a","a",'c',"d",'e','f',"g",'h'] li = ["a","b",'c',"d",'e','f',"g",'h']
li[1:] = list("hello")
print (li)
> ['a', 'h', 'e', 'l', 'l', 'o']
列表的插入:
li = ["a","b",'c',"d",'e','f',"g",'h']
li[2:2] = ""
print (li)
> ['a', 'b', '', '', '', 'c', 'd', 'e', 'f', 'g', 'h']
删除序列:
li = ["a","b",'c',"d",'e','f',"g",'h']
li[2:] = []
print (li)
> ['a', 'b'] li = ["a","b",'c',"d",'e','f',"g",'h']
li[2:len(li)] = []
print (li)
> ['a', 'b']
列表的函数:
append:向列表尾部添加元素
li = ["a","b",'c',"d"]
li.append("hello")
print (li)
> ['a', 'b', 'c', 'd', 'hello']
clear:清空列表
li = ["a","b",'c',"d"]
li.clear()
print (li)
> []
extend:修改原列表,链接两个列表产生新的列表
li_1 = ["a","b","c"]
li_2 = ["d","e","f"]
li_1.extend(li_2)
print (li_1)
> ['a', 'b', 'c', 'd', 'e', 'f'] li = ["a","b","c"]
li.extend(["d","e"]) # 先生成列表再扩展
print (li)
> ['a', 'b', 'c', 'd', 'e']
insert:将元素插入到列表的指定位置
li = ["a","b","c"]
li.insert(2,"hello") # 此处指定的位置就是元素插入进列表后的位置
print (li)
> ['a', 'b', 'hello', 'c']
index:返回列表中指定元素的下标(指定位置不存在返回异常)
li = ["a","b","c"]
print (li.index("c"))
> 2
count:返回列表中指定元素出现的次数
li = ["c","a","b","c","c"]
print (li.count("c"))
> 3
len:统计列表中元素的个数
li = ["cf","af","b",1,2]
print (len(li))
> 5 # 返回的是列表中元素的个数
pop:移除列表指定位置的元素,并返回其值(默认列表的最后一个元素)
li = ["cf","af","b",1,2]
print (li.pop())
> 2 # 默认移除最后一个元素并返回其值 li = ["cf","af","b",1,2]
print (li.pop(0))
> cf # 指定下标移除,并返回
remove:移除列表中指定的元素
li = ["cf","af","b",1,"cf",2,"cf"]
li.remove("cf")
print (li)
> ['af', 'b', 1, 'cf', 2, 'cf'] # 指定元素内容,并移除,当指定元素出现多次时,只移除第一次的出现的元素 # 移除所有指定元素:
li = ["cf","af","b",1,"cf",2,"cf"]
while "cf" in li: # 直接循环列表,确定指定元素出现的次数
li.remove("cf") # 每循环一次,移除一次
print (li)
> ['af', 'b', 1, 2]
reverse:反转列表整体元素的位置
li = [1,2,3,4,5]
li.reverse()
print (li)
> [5, 4, 3, 2, 1]
sort:对列表中的内容进行排序
li = [5,3,6,1,7]
li.sort() #直接修改原列表中的内容
print (li)
>[1,3,5,6,7]
不修改原序列排序:
#方法 1:
#利用 sorted 函数
li = [5,3,6,1,7]
new_li = sorted(li)
print (li)
print (new_li)
> [5, 3, 6, 1, 7]
> [1, 3, 5, 6, 7] #方法 2:
#创建副本 li = [5,3,6,1,7]
new_li = li[:]
new_li.sort()
print (li)
print (new_li)
> [5, 3, 6, 1, 7]
> [1, 3, 5, 6, 7]
关键字排序 key:
li = ['aa','bbbb','ccc','d']
li.sort(key = len)
print (li)
> ['d', 'aa', 'ccc', 'bbbb']
关键字排序:reverse()
li = [,,,,]
li.sort(reverse = True) # reverse = True 降序
print (li)
> [, , , , ] li = [,,,,]
li.sort(reverse = False) # reverse = False 升序
print (li)
> [, , , , ]
列表与元组的转换:
# 列表转元组:
li = [11,22,33,44]
li = tuple(li)
print (li)
> (11, 22, 33, 44) # 元组转列表:
tu = (11,22,33,44)
tu = list(tu)
print (tu)
> [11, 22, 33, 44]
字典:
dictionary 字典是 Python 语言中唯一的映射类型,也是 Python 中最强大的数据类型之一。
1、键值对的集合(map)
2、字典以大括号 "{}" 包围的数据集合
3、字典是无序的,在字典中通过键来访问成员,可变、可嵌套、可在原处修改扩展。
4、字典的键,可以是字符串(大小写敏感),数字常量或元组(不可变类型),同一个字典的键可以混用类型。字典的键必须是可哈希的。
5、字典的值可以是任意类型,可以嵌套,可以*修改。
6、映射类型对象里哈希值(键,key) 和指向的对象(值,value) 是一对多的关系,通常被认为是可变的哈希表。
7、字典对象是可变的,它是一个容器类型,能存储任意个数的 Python 对象,其中也可包括其他容器类型。
字典就是用大括号包裹的键值对集合。(键值也被称作项)
创建字典:
# 创建空字典
dic = {} # 创建字典
dic = {key1:value2,key2:value2}
dic = dict(k1='v1',k2='v2')
- 键与值用冒号 : 分开
- 项与项用逗号 , 分开
- 字典中的键必须是唯一的,值可以不唯一
字典的基本操作:
1、访问字典中的值:
dic[key] 返回键 key 对应的值 value,如果 key 不在字典中会提示错误。
2、更新字典:
# 向字典中添加一个项
dic["new_key"] = "value" # 修改字典中一个项
dic["old_key"] = "new_value" # 删除字典中的项
del dic # 删除整个字典
dic.clear() # 清空整个字典中的内容 del dic[key] # 指定key 删除某一项
dic.pop[key) # 删除指定 key 的项并返回对应的 value 值
formakeys:根据字典中所有 key 生成 一个新字典
new_dic = dic.fromkeys(['k1','k2','k3'],'v1')
print (new_dic)
> {'k2': 'v1', 'k3': 'v1', 'k1': 'v1'}
get:根据 key 取出 key 对应的 value
# dic[key] 这种方式取字典中的数据时,如果指定的 key 不存在,则退出程序并返回异常。
dic = {'k1':'v1','k2':'v2','k3':'v3'}
print (dic.get('k8'))
> None # 当指定的 key 不存在时,返回 None dic = {'k1':'v1','k2':'v2','k3':'v3'}
print (dic.get('k8','ok')) # 当 k8 不存在时,返回默认值 ok
> ok
keys:取出字典的所有 key 并以列表返回
dic = {'k1':'v1','k2':'v2','k3':'v3'}
print (dic.keys())
> dict_keys(['k1', 'k2', 'k3'])
values:取出字典的所有 value 并以列表返回
dic = {'k1':'v1','k2':'v2','k3':'v3'}
print (dic.values())
3 > dict_values(['v1', 'v2', 'v3'])
items:取出字典的所有 key 与 value 并以列表返回
dic = {'k1':'v1','k2':'v2','k3':'v3'}
print (dic.items())
> dict_items([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
循环取字典中的 Key 与 values:
dic = {'k1':'v1','k2':'v2','k3':'v3'} for k in dic.keys():
print (k)
> k3
> k2
> k1 for v in dic.values():
print (v)
> v3
> v2
> v1 for k,v in dic.items():
print (k,v)
> k3 v3
> k2 v2
> k1 v1
pop:移除字典中的某一项,并返回其 value
dic = {'k1':'v1','k2':'v2','k3':'v3'}
old_key = dic.pop('k1') # 字典是无序的 移除时必须指定移除哪一项
print (dic)
print (old_key) # 移除后会返回移除的项,指定变量接收返回值
5 > {'k2': 'v2', 'k3': 'v3'}
6 > v1
popitem:随机移除字典中的某 key 与对应的 value 并返回移除的 key 与 value
dic = {'k1':'v1','k2':'v2','k3':'v3'}
old_key = dic.popitem() # 随机移除 key 与 value
print (dic)
print (old_key)
> {'k2': 'v2', 'k3': 'v3'}
> ('k1', 'v1') # 此处返回的是元组
update:将指定字典的键值对更新至另一字典中
dic = {'name':'jay','sex':'boy',}
dicc = {'age':''} dic.update(dicc)
print ("Value: %s" % dic)
> Value: {'name': 'jay', 'age': '', 'sex': 'boy'}
setdefault(key[,default]):如果指定键在字典中,返回键对应的值,如果键不在字典中,向字典中插入这个键,并以 default 为这个键的值,反返回 default,default 值默认为 None
dic = {'name':'jay','sex':'boy','age':''}
print (dic.setdefault('age',''))
> 123 # age 键在字典中,返回字典中 age 对应的值 dic = {'name':'jay','sex':'boy','age':''}
print (dic.setdefault('qq',''))
> 123456 # qq 键不在字典中,使用指定 default 的值 123456,并将对应键值插入字典中
> {'age': '', 'sex': 'boy', 'name': 'jay', 'qq': ''}