阅读目录:
第一节:编程基础
第一节:编程基础
第二节:语言分类
第三节:高级语言的发展
第四节:程序program
第五节:Python解释器
第六节:Python基础语法
第七节:程序控制
第八节:额外扩展(以后会有介绍)
第九节:内置数据结构-数值and列表
内容:
第一节:编程基础
1、程序:
一组能让计算机识别和执行的指令
2、现代计算机结构体系-冯诺依曼体系架构
CPU由运算器和控制器组成
运算器,完成各种算数运算、逻辑运算、数据传输等数据加工处理
控制器,控制程序的执行
存储器,用于记忆程序和数据,例如内存 输入设备,将数据或者程序输入到计算机中,例 如键盘、鼠标 输出设备,将数据或程序的处理结果展示给用户, 例如显示器、打印机等3、计算机语言:
人与计算机之间的交互的语言
4、机器语言:
一定位数组成二进制的0和1的序列,称为机器指令,机器指令的结合就是机器语言
5、汇编语言:
用一些助记符号代替机器指令,称为汇编语言,如:ADD A B将寄存器A 的数和寄存器B的数相加的数放到寄存器A 中
汇编语言写好的程序需要汇编程序转换成机器指令
第二节:语言分类
1、低级语言:
面向机器的语言,包括机器语言,汇编语言
不同的机器不能通用,不同的机器需要不同的机器指令或汇编程序
2、高级语言:
接近自然和数学语言的计算机语言
高级语言手写要书写源程序,通过编译程序吧源程序转换成机器的指令程序
3、编译语言和解释语言的区别:
编译语言:把源代码转换成目标机器的cpu指令
解释语言:解释后转换成字节码,运行在虚拟机上,解释器执行中间码
如:C 、C++等语言的源代码需要本地编译
java、Pyhton、C#的源代码需要被解释器编译成中间码(Bytecode),在虚拟机上运行
第三节:高级语言的发展
1、非结构化语言:
编号或标签,GOTO,子程序可以有多个入口和出口 如:ADD A B将寄存器A 的数和寄存器B的数相加的数放到寄存器A 中
有分支,循环
2、结构化语言:
任何基本结构只允许是唯一入口或出口
有顺序,分支,循环,废弃GOTO
3、面向对象语言
更加接近人类认知世界的方式,万事万物抽象成对象,对象间关系抽象成类和继承
封装、继承、多态
4、函数式语言:
古老的编程范式,用用在数学奇数,并行处理的场景,引入到了很多现代高级语言中。
第四节:程序program
1、程序:
程序= 算法+数据结构
数据一切程序的核心
第五节:Python解释器:
官方CPython:C语言开发,最广泛的Python解释器
IPython:一个交互式,功能增强的Cpython
PyPy:Python语言写的Python解释器,JIT技术,动态编译Pyhton代码
Jython:Python的源代码编译成java的字节码,跑在JVM
IronPython:与Jython类似,运行在.NET平台上的解释器,Python代码被编译成.NET字节码
第六节:Python基础语法
1、关于编码:
在Python中 需要插入: #-*-conding:utf-8-*- ,Python3默认使用unicode编码。
gbk 两个字节表示一个字符,utf-8 三个字节表示一个字符,unicode至少两个字节。
gbk 和 utf-8 之间不能直接转换,必须通过unicode
2、注释:
单行注释使用 : # 被注释内容
多行注释使用: ''' 被注释内容 '''
3、pyc文件:
执行Python代码时,如果导入了其他的.py文件,那么执行过程中会自动产生一个与其同名的.pyc文件,该文件就是Python解释器编译之后产生的字节码。
注:字节码通过反编译可以得到代码。
4、变量:
a、声明变量:
1 name = 'JerryZao' # name是一个变量,JerryZao是变量的值
b、理解变量在内存中的变现形式
name1 = ‘jack’
给name1赋值的时候,在内存中开辟一个空间,而name1 则是存放在jack的内存地址(可以用id()查看)
c、变量的定义规则:
只能用字母,数字,下划线,不能以数字开头,不能使用关键字
5、Python的语言类型:
a、python是动态语言,强类型语言
1)静态编译语言:
实现声明变量类型,类型不能再改变, 如:int a = 10
编译时检查
2)动态编译语言:
不用事先声明类型,随时可以复制为其他类型
编译时不知道是什么类型,很难判断
3)强类型语言:
不同类型之间的操作,必须先强制类型转换为同一类型,如 : print(‘a’ + str (1))
4) 弱类型语言:
不同类型间可以操作,自动隐式转换,如:js中 console.log(1 + 'a')
6、数字:
在Python中不区分long 和 int ,所有的整形 int
整数,bool(True,False),浮点数,复数
1 num = '0011' 2 v = int(num,base = 16) # 0011作为16进制数,转换为10进制数 3 y = int(num,base = 10) 4 z = int(num,base = 2) 5 print(v,y,z) 6 7 17 11 3 8 9 10 num = '24'11 v = int(num,base = 16)12 y = int(num,base = 10)13 #z = int(num,base = 2) #错,2进制没有大于1 的数字14 print(v,y)15 16 36 24
7、字符串
使用 ' " 单双引号用的字符的序列
''' 和 """单双三引号,可以跨行、可以在其中自由的使用单双引号
在字符串前面加上R 或 r 前缀,表示该字符串不做特殊处理
8、转义序列
\\ \t \ r \n \' \"
前缀 r ,把里面的所有字符当作普通字符对待
9、缩进:
未使用C等语言的花括号,而是采用缩进的方式表示层次关系
约定使用4个空格
10、续航
在行尾使用\ ,如果使用各种括号,认为括号内是一个整体,不需要使用\
11、运算符:
a、算数运算符:
+ - * / ** // %
** :求幂
// :整除,返回商的整数部分
% :求余
b:成员运算符:
in 、 not in
1 'a' in 'sadsa'2 3 True
c、比较运算符:
== > < <= >=
!= 、 <> :表示不等于
d、逻辑运算符:
and 、 or 、not
e、赋值运算符:
= += -= += /= **= //= %=
f、位运算符:
& :按位与
| :按位或
~ :按位取反
1 0000 1100 122 1111 0011 补码 -13 1000 1101 原码 -134 5 12按位取反,是1111 0011 在计算器中认为这是补码,最高位1 ,就是负数,但是人要看原码,在补码一次,1000 1101
^ :异或(异则为 1)
<< :左移
1 a = -1 << 22 print(a)3 4 -4
1 print(~12) 13
注:
is 和 "=="的区别:
== 判断左右两边的值是否相等
is 判断内存地址是否相等, id()值来判断
小数据池 (常量池),会对字符串进行缓存,为了节省空间,id一样. str boor int 有小数据池
"在python中如果单纯定义一个字符串会被添加到小数据池中"
12、原码、反码、补码、负数
1)反码:正数的反码是原码本身,负数的反码符号为不变其余按位取反
2)补码:正数的补码的原码本身,负数的补码符号位不变其余为按位取反后+1
1 5-12 5的原码+ -1 的补码
1 10 ^ 9 2 3 0000 1010 10 4 0000 1001 9 5 0000 0011 3 6 7 10^-9 8 9 0000 110010 1000 1001 -9反码11 1111 0111 -9补码12 1111 1101 异或的补码13 1000 0011
13、运算符优先级:
算数运算符 > 位运算符> 身份(成员)运算符 > 成员运算符 > 逻辑运算符
第七节:程序控制
1、常用控制结构:顺序,分支,循环
2、单分支结构
1 if conditon:2 代码块3 condition必须是一个bool类型,这个地方有一个隐式转换bool(condition)4 5 代码块:6 类似于if 语句的冒号后面的就是一个语句块7 在if、for 、def、class等关键字后使用代码块
3、多分支结构:
1 if...elif...else语句 2 if condition1: 3 代码块1 4 elif condition2: 5 代码块2 6 elif condition3: 7 代码块3 8 ...... 9 else:10 代码块
4、分支嵌套:
1 score = 80 2 if score<0: 3 print('wrong') 4 else: 5 if score==0: 6 print('egg') 7 elif score <= 100: 8 print('right') 9 else:10 print('too big')
5、循环语句——while语句
1 语法2 while condition:3 block4 当条件满足即condition为True,进入循环体,执行block5 举例6 flag=107 while flag:8 print(flag)9 flag -= 1
6、循环——for语句
1 语法2 for element in iteratable:3 block4 当可迭代对象中有元素可以迭代,进入循环体,执行block
注:
a、range()函数:
a = range(1,4)
print(a)a 是一个可迭代对象
1 a = range(1,8,2) 2 b = range(1,8,-1) 3 c = range(8,1,-1) 4 d = range(0) 5 6 for i in c: 7 print(i) 8 9 810 711 612 513 414 315 2
7、循环continue语句
8、循环 break语句
1 count = 02 for i in range(0,1000,7):3 print(i)4 count += 15 if count >= 20:6 break
1 0 2 7 3 14 4 21 5 28 6 35 7 42 8 49 9 5610 6311 7012 7713 8414 9115 9816 10517 11218 11919 12620 133
总结:
continue和break是循环的控制语句,只影响当前循环,包括while、for循环 如果循环嵌套, continue和break也只影响语句所在的那一层循环 continue和break 不是跳出语句块,所以 if cond: break 不是跳出if,而是终止if外的break所 在的循环
第八节:额外扩展(以后会有介绍)
1、引用计数:
1 import sys2 3 sys.getrefcount(x)
2、内置函数divmod()
divmod(54321,10000)
----> (5, 4321)
1 divmod(x, y, /)2 Return the tuple (x//y, x%y). Invariant: div*y + mod == x.
3、判断是否是偶数的方式
1 i & 1 按位与,奇数的话,各位肯定是1,偶数各位肯定是0
第九节:内置数据结构-数值and列表
1、分类:
-
-
- 数值型
-
int、 float、complex(复数,不常用),boo
-
-
- 序列对象
-
字符串str、 列表list 、元组tuple
-
-
- 键值对
-
集合set、字典dict
*2、数值型:
-
- 数值型
int,float,complex。bool都是class,而具体的数据 1,2.2等都是对象即实例。
注:bool是 int 的子类,仅有True 和 False 对应1 、0,可以和整数直接运算
-
- 类型转换(built-in)
int(x),float(x),complex(x), bool(x)
3、数字的处理函数:
首先导入 math 模块,使用 round() ,floor(), ceil() int() //
1 a = int(2.5) 2 b = int(2.1) 3 c = int(2.6) 4 d = int(-2.4) 5 e = int(-2.5) 6 f = int(-2.7) 7 print(a,b,c,d,e,f) 8 9 2 2 2 -2 -2 -210 11 # int 就是对浮点数取整数部分
1 import math2 3 print(math.floor(2.5),math.floor(-2.5)) # 向地板 2 -34 print(math.ceil(2.5),math.ceil(-2.5)) # 向天花板 3 -2
1 print(7//2,7//-2,-7//2,-(7//2)) # 向下取整 3 -4 -4 -32 print(2//3,-2//3,-1//3) # 0 -1 -1
1 print(round(2.5),round(2.5001),round(2.6)) # 2 3 3 四舍六入五取偶(取偶是取离其最近的偶数)2 (不是严格的四舍六入,只要大于5就入,小于5就舍)
4、数字的处理函数
min()、max()、pow()== x**y、math.sqrt() 开方
进制函数,返回值是字符串:bin() oct() hex()
math.pi -----π math.e 自如常数
1 bin(2) # '0b10' 是字符串2 oct(8) # '0o10'3 0x10 # 16 是数字 int
import mathmath.sqrt(9)3.0 得到的是浮点数
5、类型判断:
type(obj),返回类型,而不是字符串
a = 1type(a)得到str,但是 str 没有引号!! 是 str 类
1 type(1 + True + 2.1) # float 2 3 type(True+ 1) # int
注:
只要有浮点数,就有隐式转换 ,变为 float 型
不同的类型之间不能比较,但是可以用 == 或 !=
isinstance(obj,class_or_tuple):返回bool值
1 isinstance('a',str) # True2 isinstance(1,(str,bool))# False bool虽然是int的子集,但是也不对3 isinstance(1,(str,bool,int)) # True
1 In [61]: isinstance(1,bool)2 Out[61]: False3 4 In [62]: isinstance(False ,bool)5 Out[62]: True6 7 In [63]: isinstance(False , int)8 Out[63]: True
*6、列表 list
列表的特点:
-
-
- 列表内的个体称为元素,由若干个元素组成列表
- 元素可以是任意的
- 列表内元素有顺序,可以索引
- 列表的元素可以被迭代
- 线性的数据结构
- 使用 [ ] 表示
- 列表是可变的
-
列表list 、链表 linked、队列queue、 stack栈的差异:
-
-
- 列表:连续的内存空间,有序的,可索引的,追加(O(1)),查询都很快(通过索引值,偏移量),但是删除、增加元素,比较慢,需要遍历元素
- 链表:非连续的内存空间,但是也是有序的,可以索引(在内存空间中是散落的,但是内存地址不是连续的),查询比较慢,都得从开头找,插队,删除都比较快,只需要找前后的内存地址就可以。
- 队列:先进先出,基于地址指正遍历数据可以从进的一端或者出的一端 ,但是不能同时访问,不需要开辟新的空间
- 栈:后进先出,遍历数据只能从入口端遍历,如果查找一个最先放进去的数据,需要遍历所有的数据,同时遍历数据需要开辟新的内存空间
-
列表定义,初始化:
方法一:[ ]
方法二:list(iterable)
注:列表不能一开始就定义大小,但是会有一个大概的内存空间。
1 l = list()2 l = []3 l = [2,3,4,[2,3,4]]4 l = list(range(5))
列表索引访问:
索引,也叫下标
正索引:从左到右,从0开始
负索引:从右到左,从-1开始
索引都不可以越界,否则会出现IndexError
列表通过索引访问:list [index]
1 l = list(range(5)) # [0, 1, 2, 3, 4]2 print(l[-2]) # 3
列表查询:
index(value,[ start,[stop ] ]) # a = l.index(4,6,8) ,6 和 8是索引,但是这里不能用负数做索引
通过值value ,从指定区间查找列表内的元素是否匹配
匹配到第一个就立即返回索引
匹配不到,抛出ValueError 异常
1 l = list(range(1,5)) [1,2,3,4]2 a = l.index(1)3 print(a) # 0
count(value)
返回列表中匹配Value的次数, 如果 value 不存在,不会抛异常
1 l = list(range(1,5)) 2 b = l.count(5)3 print(b) # 0
时间复杂度:
index 和 count 方法都是O(n)
随着列表数据规模的增大,而效率下降,而且两者都要遍历,所以一般都少用!!!!
n:元素的个数
O(1):表示一步到位,如后面说的append()
返回列表元素的个数:
len(l):默认不需要遍历,会在列表最后有记录
注:有顺序的可以索引,但不一定可以迭代
列表元素修改:
索引访问修改:
list [ index ] = value 注:index不能越界,抛出 IndexError异常
1 l = [1,2,3,4]2 l[2] = 3333 print(l) # [1, 2, 333, 4]
列表增加、插入元素:(一次只能插,追加一个元素)
append(object) 返回 None,也就意味着在原列表追加,时间复杂度为O(1),一步到位。
insert(index,obj)返回None,时间复杂度为 O(n),所以少用。
注: 所以可以越界,越上界,尾部追加,否则,首部追加,没有任何意义!
1 l = [1,2,3,4] 2 l.append('a') # append()是把任何当成一个具体对象,直接追加到最后,而且只能表示为一个,否则抛出SyntaxError 3 l.append(range(5)) 4 l.append([2,3,3]) 5 print(l) # [1, 2, 3, 4, 'a', range(0, 5), [2, 3, 3]] 6 7 8 9 l = [1,2,3,4]10 l.insert(0,2)11 l.insert(3,[2,3,4])12 print(l) # [2, 1, 2, [2, 3, 4], 3, 4]
extend(iteratable) 返回None
1 l = [1,2,3,4,4,4,435,4,35,435,3]2 l.extend(range(5))3 print(l) # [1, 2, 3, 4, 4, 4, 435, 4, 35, 435, 3, 0, 1, 2, 3, 4]
+ 生成新的 list
1 l = [1,2,3,4,35,435,3]2 a = l + [55,55]3 print(a) # [1, 2, 3, 4, 35, 435, 3, 55, 55]4 print(l) # [1, 2, 3, 4, 35, 435, 3]
* 生成新的list
1 l = [1,2,3,4,35,435,3]2 a = l * 23 print(a) # [1, 2, 3, 4, 35, 435, 3, 1, 2, 3, 4, 35, 435, 3]4 print(l) # [1, 2, 3, 4, 35, 435, 3]
注: * 使用的坑:
1 x = [[1,2,3]]*22 print(x) # [[1, 2, 3], [1, 2, 3]]3 print(x[1][2]) # 34 5 y = [1] * 56 print(y) # [1, 1, 1, 1, 1]
注:关于 *
1 l1 = [1,2,3,3] 2 l2 = l1 * 3 3 l1[2] = 0 4 l2[2] = 0 5 print(l1) 6 print(l2) 7 -----------------------> 8 [1, 2, 0, 3] 9 [1, 2, 0, 3, 1, 2, 3, 3, 1, 2, 3, 3]10 11 12 13 l1 = [[1,2]] # 里边的 [1,2]是一个地址引用,放的是地址,所以乘3 就是地址复制三分(不同于上面例子,单个简单元素)14 l2 = l1 * 315 l2[1][1] = 616 print(l2)17 ----------------------->18 [[1, 6], [1, 6], [1, 6]]
l2[2] = 99
print(l2) # [[1, 2], [1, 2], 99]19 20 21 l1 = [[1,2],[1,2],[1,2]] # 因为不是同一个地址,不像上面,*3 形成,所以只改一个22 l1[2][1] = 623 print(l1)24 ----------------------->25 [[1, 2], [1, 2], [1, 6]]
列表删除元素:
remove(value) :返回None,在原列表删除,O(n)
pop([ index ])-- item
不指定索引,就从列表的尾部弹出一个元素
指定索引,就从索引弹出一个元素,索引越界 抛出IndexError
clear()--- 返回None
清除列表的所有元素,剩下一个空列表
列表的其他操作:
reverse() :返回None
将列表元素反转,就地修改
sort( key = None,reverse = False) 返回None
对列表元素进行排序,就地修改,默认升序
reverse = True ,反转,降序
key 一个函数,指定key 如何排序
lsi.sort(key = functionname)
sort(key=str,reverse=True) # 元素以str 排序
in : [3,4] in [1,2,[3,4]] , for x in [1,2,3,4]
注:Python中是没有变量的!
随机数:random模块
random.randint() # 闭区间的整数 random.randint(2,3) ,返回int类型
random.randrange() # 左闭右开 random.range(1,7,2),返回int类型
random.choice(iteration) # 随机去一个,但是原数据集不变
1 l = [1,2,34,4,'s']2 print(random.choice(l))3 print(l)
random.shuffle() # 就地修改,返回None,(洗牌,打乱)
1 l = [1,2,34,4,'s']2 print(random.shuffle(l))3 print(l)4 5 None6 [2, 4, 34, 1, 's']
random.sample(ierater,k) # 取k个不同的元素 (理解这里的不同:l[1] = l[2] ,但是是不同的元素) ,返回一个新列表
random.sample(['a','b','c','d'],2)
random.sample(['a','a','a'],2) # ['a','a']
1 l = [1,2,3,4,2,2,2,2,2,34,4,'s']2 print(random.sample(l,3))3 print(l)4 5 [2, 2, 4]6 [1, 2, 3, 4, 2, 2, 2, 2, 2, 34, 4, 's']
**列表的复制:浅复制,深复制
---------------------> 赋值
1 l1 = list(range(5))2 l2 = list(range(5))3 print(l1 == l2) # == 内容相同4 l3 = l15 l1[2] = 96 print(l3)7 ---------------------->8 True9 [0, 1, 9, 3, 4]
In [106]: l1 = [1,2,3,[4,5]]
In [107]: l2 = l1
In [108]: l2[1] = 22
In [109]: l2[3][1] = 55
In [110]: l1
Out[110]: [1, 22, 3, [4, 55]]In [111]: l2
Out[111]: [1, 22, 3, [4, 55]]
------> copy,生成新的列表(shadow copy 影子拷贝)
1 l1 = list(range(4)) 2 l2 = l1.copy() 3 print(l2) 4 l2[2] = 99 5 print(l1,l2) # [0, 1, 2, 3] [0, 1, 99, 3] 6 7 l3 = [1,2,3,[5,6]] 8 l4 = l3.copy() 9 print(l4)10 # l3[3] = 1011 # print(l3,l4) # [1, 2, 3, 10] [1, 2, 3, [5, 6]]12 l3[3][1] = 913 print(l3,l4) # [1, 2, 3, [5, 9]] [1, 2, 3, [5, 9]]
------> deepcopy,深拷贝
1 import copy 2 l1 = [1,2,3] 3 l2 = copy.deepcopy(l1) 4 # print(l2) 5 l2[2] = 99 6 # print(l2) [1, 2, 99] 7 l3 = [1,2,[3,4]] 8 l4 = copy.deepcopy(l3) 9 print(l4)10 l3[2][1] = 9911 print(l3,l4) # [1, 2, [3, 99]] [1, 2, [3, 4]]12 13 l3[2] = 99914 print(l3,l4) #[1, 2, 999] [1, 2, [3, 4]]
列表补充:
1、切片:
1 li = [1, 12, 3, 4, [2, 2, [3, 4]], 2, '232', 'dsd'] 2 a = li[0] 3 print(a) 4 b = li[0:1] 5 print(b) 6 c = li[0:-1] 7 print(c) 8 d = li[0:5:2] #从左往右隔一个取值 9 print(d)10 e = li[-1::-1] #从右往左一个一个取11 print(e)12 f = li[-1::-2] # 从右往左隔一个取13 print(f)14 g = li[-1::-3]15 print(g)16 h = li[1:]17 print(h)18 i = li[:]19 print(i)20 21 122 [1]23 [1, 12, 3, 4, [2, 2, [3, 4]], 2, '232']24 [1, 3, [2, 2, [3, 4]]]25 ['dsd', '232', 2, [2, 2, [3, 4]], 4, 3, 12, 1]26 ['dsd', 2, 4, 12]27 ['dsd', [2, 2, [3, 4]], 12]28 [12, 3, 4, [2, 2, [3, 4]], 2, '232', 'dsd']29 [1, 12, 3, 4, [2, 2, [3, 4]], 2, '232', 'dsd']
2、连接成字符串:(全是字符串的元素 才可以)
1 li1 = ['ww','wwwq','wqw']2 s = ''.join(li1)3 print(s)4 5 wwwwwqwqw 元组也可以:
tu = ('ss','we',)
s = ''.join(tu)print(s)
3、del 删除元素
1 a = [1,2,3,4]2 del a[1]3 print(a)
[1, 3, 4]
注:del是根据索引删除元素,remove是根据元素删除,从左往右,第一个匹配到的
4、列表如何转换为字符串:
列表转换为字符串,在列表基本操作里介绍了tu = (11, 22, 33, [9, 3], 44,)s = ''for i in tu: s = s + str(i)print(s) print(type(s)) #