VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • python基础总结

第一章 python基础

初识

  1. cpu 内存 硬盘 操作系统

    cpu:计算机的运算和计算中心,相当于人类大脑。
    ​ 内存:暂时存储数据,临时加载数据应用程序,运行速度快,高铁,断电即消失,造价很高。
    ​ 硬盘:磁盘,长期存储数据。
    ​ 操作系统:一个软件,连接计算机的硬件与所有软件之间的一个软件。

  2. python的编程语言分类

    • 编译型:将代码一次性全部编译成二进制,然后再执行。优点:执行效率高。缺点:开发效率低,不能跨平台。代表语言:C

    • 解释型:逐行解释成二进制,逐行运行。优点:开发效率高,可以跨平台。缺点:执行效率低。代表语言:python。

  3. python的种类

    • Cpython:官方推荐解释器。可以转化成C语言能识别的字节码。
    • Jpython: 可以转化成Java语言能识别的字节码。
    • Ironpython:可以转化成.net语言能识别的字节码
    • pypy: 动态编译。
      ......
  4. 变量:只是指向某种数据

  5. 常量:python中没有真正的常量,为了应和其他语言的口味,全部大写的变量称之为常量。

  6. while/for 的else:如果循环没有被break终止则else语句会被执行,如果while被break终止,则不执行else语句。

  7. 运算符:算数运算符+、-等;比较运算符>、==等;赋值运算符=、+=等;逻辑运算符not、and、or;成员运算符in、not in。
    and or not

    • 在没有()的情况下,优先级:not > and > or,同一优先级从左至右依次计算
  8. 三元运算符:简单的if-else语句可以简化为三元运算符。如判断a,b的大小c = a if a>b else b

  9. 编写代码原则:开放封闭原则,代码对于未来的一些拓展一定是要开放的(接口)可以添加一些功能。
    开放封闭原则:
    开放:对源码的拓展是开放的。
    封闭:对源码的修改是封闭的。

*的魔术用法:

*的聚合:用于万能形参,在函数的定义时, *将所有的位置实参聚合成一个元祖,将这个元祖赋值给args。**将所有的关键字参数聚合成一个一个字典,将这个字典赋值给kargs。

*的打散,在函数的调用时*打散的是迭代对象,必须用在可迭代对象上(str,list等)**打散的是字典。

def func(*args):
    print(args)
funs([1,2,3],[4,5,6])   #([1, 2, 3], [4, 5, 6])
funs(*[1,2,3],*[4,5,6])     #*的打散,等同于funs(1, 2, 3, 4, 5, 6)
#(1, 2, 3, 4, 5, 6)

def func(*args,**kargs):
    print(args)
    print(kargs)
funs({'百度网盘群': '980173694'})
#({'百度网盘群': '980173694'})  {}

funs(**{'百度网盘群': '980173694'})#**的打散,等同于funs(百度网盘群='980173694')
#()  {'number': '980173694', 'massage': '欢迎加入百度网盘群'}

格式化输出(3.6版本之后)

基础表达:

name = 'python'
age = '18'
msg = f'我叫{name},今年{age}'    #在引号前添加一个字符f

可以加表达式:

count = 2
print(f'最终结果:{count**2}')
name = 'python'
print(f'我的名字是{name.upper()}')
dic = {'name':'python','age':'18'}
msg = f'我叫{dic["name"]},今年{dic["age"]}'   #注意双引号与单引号的使
list = ['python','18']
msg = f'我叫{list[0]},今年{list[1]}'

可以结合函数:

def sum1(a,b):
    return a+b
print(f'最终结果是{sum1(1,2)}')

优点:1.结构更加优化。2.可以结合表达式和函数使用。3.效率更高

编码

计算机存储文件,存储数据,以及通过网络发送出去,储存发送数据底层都是0与1的二进制。
密码本:0101011001 二进制与文字之间的关系

ASCII码:只包含英文字母,数字,特殊字符。共8位,但只用了7位,可以表示128(2**7)个不同的字符。ASCII码预留了一位,第8位为0。

字节:8bit(位) = 1byte(字节)

中国:gbk(最多能表示2**16个中文),只包含英文字母,数字,特殊字符(ASCII)和中文,也叫国标(国家标准)。一个英文字母用一个字节表示,一个中文用两个字节。

Unicode:万国码:把世界上的所有的文字都记录到这个密码本。用4个字节表示,可表示2**32=4294967296个文字。

utf-8:(Unicodes升级版本)最少用1个字节表示字符(英语),欧洲用2个字节,中文用3个字节
'我们12ax' :GBK :8个字节
'我们12ax' :UTF-8:10个字节

单位的转换:
8bit = 1byte
1024byte = 1kb
1024kb = 1MB
......GB、TB、PB、EB、 ZB 、YB、 NB

不同的编码方式之间不能相互识别:

  • 数据在内存中全部是以Unicode编码的,但是当数据用于网络传输或者存储到硬盘中,必须是以非Unicode编码(utf-8、gbk等)

  • python中的数据从内存(Unicode编码)存储到硬盘或进行网络传输时要经历一个特殊的转化过程,要转化为一个非Unicode编码类型的特殊数据才能进行传输或储存至硬盘,即bytes类型(内存中的编码方式:非Unicode)

  • bytes与str的操作方式大部分都是一样,bytes can only contain ASCII literal characters,bytes用于文件的储存、网络的传输等。直接将非ASCII码字符串转化为bytes类型会报错,要使用encode()

    #ASCII码中的字符转bytes:
    a = b'iloveyou'
    print(a,type(a))  #b'iloveyou' <class 'bytes'>
    
    #将中文转化为bytes类型:
    b = b'山就在那儿'
    print(b)
    #SyntaxError: bytes can only contain ASCII literal characters
    
    #正确方法为:
    c = '山就在那儿'
    b = c.encode('utf-8')
    print(c.encode('utf-8'))    #一般指定utf-8的编码形式,   (encode:编码)
    >>>b'\xe5\xb1\xb1\xe5\xb0\xb1\xe5\x9c\xa8\xe9\x82\xa3\xe5\x84\xbf'
    
  • bytes可转化为字符串类型(Unicode)(decode,解码)。用什么编码类型转换为bytes数据类型的就用什么解码。

    b = b'\xe5\xb1\xb1\xe5\xb0\xb1\xe5\x9c\xa8\xe9\x82\xa3\xe5\x84\xbf'
    print(b.decode('utf-8'))   #山就在那儿
    
    #用什么编码类型转换为bytes数据类型的就用什么解码。
    b = b'\xe5\xb1\xb1\xe5\xb0\xb1\xe5\x9c\xa8\xe9\x82\xa3\xe5\x84\xbf'
    c = b.decode('gbk')
    print(c)
    >>>UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 14: incomplete multibyte sequence
    

小题试做:gbk转换为utf-8

#分析,所有的编码都与Unicode有关(计算机内存中以Unicode编码),因此可先将gbk转换为Unicode编码,再转换为utf-8编码。
gbk = b'\xc9\xbd\xbe\xcd\xd4\xda\xc4\xc7\xb6\xf9'
decode1 = gbk.decode('gbk')    #解码为Unicode编码的字符串,可print(decode1)查看。
print(decode1.encode('utf-8'))  #以utf-8编码
>>>b'\xe5\xb1\xb1\xe5\xb0\xb1\xe5\x9c\xa8\xe9\x82\xa3\xe5\x84\xbf'

数据类型

数据类型的分类(可变与不可变):

  • 可变(不可哈希)的数据类型:list dict set(集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键))
  • 不可变的数据类型(可哈希): str bool int tuple(该对象本身不可变),(做不可变类型做任何操作,方法都不会改变原对象)

数据之间类型的转换

  • int bool str 三者转换

  • str list 两者转换

  • list set 两者转换

  • str bytes 两者转换,只有字符串能和bytes互换。

  • 所有数据都可以转换成bool值,转换成bool值为False的数据类型有:

    '',0,(),{},[],set(),None
    

按照储存空间的占用分(从低到高)

  • int
  • str
  • set : 无序
  • tuple: 有序,不可变
  • list: 有序,可变
  • dict: 有序(3.6版本之后),可变

序列化

结构化数据:内存中的数据是结构化数据,存在许多指针(有指向关系的数据)。将数据组合为有指向关系的数据是结构化的过程。

线性数据:磁盘中的文件是一个典型的线性数据,数据间没有引用关系。

序列化(serialization):将内存中的数据结构(list、str、tuple、dict、set等)转换成字节或字符串,用以保存在文件或通过网络传输,称为序列化过程。

反序列化(deserilzation):从磁盘文件中,网络中获取的数据类型(字节),转换成内存中原来的数据数据结构,称为反序列化过程。

序列化模块:json、pickle、shelve等

软件开发规范

配置文件(conf-setting.py):静态(变量不能改变只能引用)的路径,数据库连接的设置

主逻辑函数(core-src.py):

公共组件(lib-common):装饰器、日志函数、

启动函数(bin-starts.py):只有一个文件。

数据库(db-register):文本数据

日志(log-access.log):日志的数据

READEME

str

存储少量的数据。切片还是对其进行任何操作,获取的内容全都是str类型,存储的数据单一。

capitalize() 首字母(第一个单词)大写,其余变小写

title() 每个单词的首字母大写。(以特殊字符(非字母)隔开的即为一个单词)

swapcase() 大小写翻转

center() 居中,有1个必选参数:宽度,一个非必选参数:填充)

find() 通过元素找索引,找到第一个就返回索引,找不到返回-1。

index() 通过元素找索引,找到第一个就返回索引,找不到就报错。

list

列表可以储存大量的数据,但数据间的关联性不强且列表的查询速度比字典慢。

在列表末尾增加一个数据项(list.append()方法),直接修改列表没有返回值。

在列表末尾增加一个数据项集合( 添加多个元素的方法,迭代追加)(list.extend()方法);

l1 = [1,2]
l1.extend('abcd')
print(l1)
>>>[1, 2, 'a', 'b', 'c', 'd']
l2 = [1,2]
l2.extend(['asd',1,2])
print(l2)
>>>[1, 2, 'asd', 1, 2]

列表的特殊插入法,在特定位置增加一个数据项(list.insert()方法)不推荐使用,降低性能:

a=['b','c','d']
a.insert(0,'a')
a[0:1]      #['a']

从列表末尾删除数据,按照索引删除(list.pop()方法),若果没有给出索引值则默认删除最后列表的一个元素,有返回值,返回删除的元素,不推荐使用pop(n),降低性能。

l1 = [1,2,3,4]
print(l1.pop(0))    #1

在列表中删除一个特定项(list.remove()方法);如果有重复的则默认删除第一个元素(从左开始)

list.clear()清空列表的方法,del 按照索引删除,也可以按照切片删除(可加步长),无返回值

l1 = [1,2,3,4,5,6]
del l1[0]
print(l1)       #[2.3.4,5,6]

del l1[0:4:2]
print(l1)       #[3,5,6]

按照索引改元素;按照切片更改元素(迭代增加),也可按照切片加步长更改,但必须一 一 对应。

l1 = [1,2,3,4]
l1[0] = 0

l1[1:] = 'abcd'
print(l1)
>>>[0, 'a', 'b', 'c', 'd']

l1[::2]='123'
print(l1)
>>>['1', 'a', '2', 'c', '3']

index() 通过元素找索引

sort() 默认从小到大排序,设置reverse参数则可从小到大。

reverse() 反转

列表相加 (3.4以上版本)

列表与数字相乘 (3.4以上版本)

l1 = [2,'a',[1,'b']]
l2 = l1*3
print(l2)
>>>[2, 'a', [1, 'b'], 2, 'a', [1, 'b'], 2, 'a', [1, 'b']]

列表的特殊性:正向循环一个列表时如果删除某个元素,那么这个元素后面的所有元素都会向前进一位,它们的索引相比之前也会前进一位,因此,在循环一个列表时的过程中,如果要改变列表的大小(增加值或者删除值),那么结果很可能会出错或者报错。

l1 = [1,2,3,4,5,6]  #删除列表中索引位为偶数的元素。
for i in range(0,len(l1),2):
    l1.pop(i)
print(l1)
>>>IndexError: pop index out of range

解决此问题有三种方式:

1.直接删除 (按照元素删除,按照索引删除,切片加步长

#切片加步长
l1 = [1,2,3,4,5,6]
del l1[1::2]
print(l1)

2.倒叙删除

l1 = [1,2,3,4,5,6]
for i in range(len(l1)-1,-1,-2):
    l1.pop(i)
print(l1)
>>>[1,3,5]

#不能用以下代码;
l1 = [1,2,3,4,5,6]
for i in range(1,len(l1),2):
    l1.pop(-i)

3.思维转换

l1 = [1,2,3,4,5,6]
l2 = []
for i in range(0,len(l1),2):
    l2.append(l1[i])
l1 = l2
print(l1)

b=sorted(a,reverse=True) 函数按照长短、大小、英文字母的顺序给列表中的元素进行排序,但不会改变列表本身

列表是有序的,可以用enumerate()函数在索引的时候得到每个元素的具体位置:

l1 = ['a','b','c']
for num,int in enumerate(l1):
print(num,int)
>>>0 a
1 b
2 c

列表的嵌套

列表推导式:用一行代码构建一个比较复杂有规律的列表。

l1 = [i for i in range(10)]  #可将range换为可迭代对象。

列表推导式可分为两类。

  • 循环模式:需遍历每一个元素。[变量(加工后的变量) for 变量 in iterable]
#例1:将10以内所有整数的平方写入列表:
l1 = [i*i for i in range(11)]
print(l1)
#例2:100以内的所有奇数写入列表:
l1 = [i for i in range(1,100,2)]
print(l1)
#例3:从python1到python10写入列表:
l1 = [f'python{i}' for i in range(1,11)]
print(l1)
  • 筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]
#例1:将10以内能够被2整除的数写入列表
l1 = [i for i in range(11) if i%2==0]
print(l1)
#例2:过滤列表l1中小于3的字符串,将剩下的转换成大写。l1 = ['nonl','globals','as','in']
l1 = ['nonl','globals','as','in']
l2 = [i.upper() for i in l1 if len(i)>=3]
print(l2)
#例3:将num列表中含有两个0的字符串生成一个新列表。num = [['021','001','201'],['100','012','010']]
l1 = [j for i in num for j in i if j.count('0') == 2]
print(l1)

缺点:

  1. 只能构建计较复杂并且有规律的列表;
  2. 超过三层循环才能构建成功的,不建议使用列表推导式;
  3. 无法找查错误(debug模式)

tuple

为只读列表。可存大量的数据,可以索引,切片(按步长),不可更改,但元祖中列表里的元素可以按照列表更改,示例: (1, True, [1, 2, 3])。

特殊性:元祖中只有一个元素,并且没有’,‘,则它不是元祖,它与括号中的数据类型一致

print(type((1,2))) #<class 'tuple'>
print(type((1)))   #<class 'int'>
print(type((1,)))   # <class 'tuple'>

count() 计数

index() 找索引

元祖的拆包:分别赋值,必须一 一对应。(列表也可以拆包,但一般不用)

a,b=(1,2)
print(a,b)    #1 2

#与*(聚合)使用:
a,b,*c = (1,2,3,4,5,6,7,)
print(a,b,c)    #1 2 [3, 4, 5, 6, 7]

a,*b,c = (1,2,3,4,5,6,7,)
print(a,b,c)      #1 [2, 3, 4, 5, 6] 7

a,*b,c = [1,2,3,4,5,6,7,]
print(a,b,c)      #1 [2, 3, 4, 5, 6] 7

a,*b,c=range(10)
print(a,b,c)       #0 [1, 2, 3, 4, 5, 6, 7, 8] 9

字典

键必须是不可变的数据类型,最常用的是str int,键是不能改变且无法修改,而值可以改变,可修改,可以是任何对象。键是不能重复的,而值可以重复。字典在3.5x版本之前(包括3.5)是无序的;字典在3.6x会按照初次建立字典的顺序排序的,学术上不认为是有序的。字典3.7x以后都是有序的。字典以空间换时间,查询速度非常快,内存消耗巨大。

字典的创建方式:

dic = dict((('i',1),('love',2),('you',3)))  #用列表也可以dic = dict([('i',1),('love',2),('you',3)]),列表或元祖中的每个元素是一个二元组就可以用dict()转换为字典。
print(dic)
>>>{'i': 1, 'love': 2, 'you': 3}

dic = dict(i=1,love=2,you=3)
print(dic)
>>>{'i': 1, 'love': 2, 'you': 3}

dic = dict({'i': 1, 'love': 2, 'you': 3})
print(dic)
>>>{'i': 1, 'love': 2, 'you': 3}

#字典推导式
dic = {i:i+1 for i in range(3)}

增,添加多个元素的方法:

update():有键则改,无键则增加。

setdefault():有则不变,无则增加

fromkeys():第一个参数必须为可迭代对象,可迭代的对象共用第二个参数(id相同)。

dic = {}
dic['age'] = '18'

dic.setdefault('able')
print(dic)      #{'able':None}
dic.setdefault('hobby':python)

dic = dict.fromkeys('abc',1)
print(dic)      #{'a': 1, 'b': 1, 'c': 1}

dic = dict.fromkeys([1,2,3],[])
print(dic)    #{1: [], 2: [], 3: []}

dic[1].append('a')
print(dic)      #{1: ['a'], 2: ['a'], 3: ['a']}

删:

popitem() 3.5版本之前,随机删除,3.6版本之后,删除最后一个,有返回值。

pop(),按照键删除,有返回值,返回的为字典的值,如果没有要删除的键,则会报错,但可以设置第二个两个参数,无论字典中是否有此键,都不会报错,若有此键则返回值为此键的值,若无此键则,返回设置的参数。

del,若无键会报错,不推荐使用

clear 清空

dic = {}
print(dic.pop('hobby','没有此键值对'))    #没有此键值对。
del dic['age']   #报错
dic.claer()

dic['name'] = 18

update() 有则覆盖,无则增加

#1.增加/改键值对
dic0 = {1:'i'}
dic1 = {3: 'c'}
dic0.update(a='love')   #a位置不能是int类型
dic0.update(dic)

dic = {'name':'山就在那儿','hobby_list':['book','python']}
print(dic['hobby_list'])  #若没有此键则会报错,不建议用

l1 = dic.get('hobby_list')   #若没有键则会返回None,可以定义第二个参数,第二个参数即为返回值

#keys()
print(dic.keys())   #会返回一个dict_keys类型,包含字典中所有的键,和列表相似,但不能索引,转化成列表后可遍历
>>>dict_keys(['name', 'hobby_list'])

#values()
print(dic.values())   #会返回一个dict_values类型,包含字典中所有的值,和列表相似,但不能索引,可转化成列表后可遍历
>>>dict_values(['山就在那儿', ['book', 'python']])

#items()
for k,v in dic.items():     #元祖的拆包  for i in dic.items()  print(i)   打印的结果数据为元祖

#小题试做:将字典dic中的以‘k’开头的键值对删除,(循环一个字典时,若果改变字典的大小则或报错。)
dic = {'k1':'a','k2':'b','k3':'c','a':'d'}
l1 = []
for key in dic:
    if key.startswith('k'):
        l1.append(key)
for i in l1:
    dic.pop(i)
#改进
for key in list(dic.keys()):   #将其转换为一个列表,若不加list则会报错。
    if 'k' in key:
        dic.pop(key)

字典的嵌套

字典推导式

l1 = ['1','2','3']
l2 = ['一''二''三']
dic = {l1[i]:l2[i] for i in range(len(l1))}

set

集合:容器型数据类型,要求它里面的元素是不可变的数据(可哈希),但它本身是可变的数据类型(不可哈希)。集合是无序的。以{}存放数据。

作用:列表的去重;关系的测试(交集,并集…)

集合的创建:

set = {1,2'a'}
#空集合的表示:
set1 = set()   #set1 = {}表示空字典

增:add()、update():迭代增加,有重复的则去重

set1 = {1,2}
set1.add('a')

set1.update('asdfdsa')
print(set1)
>>>{'a', 1, 2, 'f', 's', 'd'}

删:remove()(按照元素删除,pop()随机删除,clear()清空集合,del 删除集合,discard()有则删除,无则pass,不报错。

改:先删除再增加

交集。(&或者intersection) 集合共同有的元素

set1 = {1,2,3}
set2 = {2,3,4}
print(set1 & set2) #or print(set1.intersection)

并集。(|或者union)集合所有的元素

set1 = {1,2}
set2 = {2,3}
print(set1 | set2) #or print(set1.union(set2))

差集 ( - 或者difference) ,前一集合独有的元素

set1 = {1,2,3,4,5}
set2 = {2,4,6}
print(set1 - set2) #or print(set1.difference(set2))

反交集。(^ 或者symmetric_difference)每个集合独有的元素

set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(set1 ^ set2) #or print(set1.symmetric_difference(set2))
>>>{1,2,6,7}

子集与超集

set1 = {1,2}
set2 = {1