首页 > 代码库 > 第三周总结

第三周总结

一、基础概念

1、集合:

集合是一个无序的、不重复的数据组,它的作用:

1)、去重复、把一个列表变成集合,就会自动去重

2)、关系测试,测试两组数据之间的交集、差集、并集等关系

集合的方法:

a、设置集合

>>>list_1 = [1,3,5,6,77,3,12]   #列表1
>>>list_2 = [1,3,88,4,33,77]  #列表2
>>>list_1 = set(list_1)  #通过set方法可以将列表变为集合
>>>list_1
{1, 3, 5, 6, 12,77}  #集合list_1现在已经去重
>>>list_2 = set(list_2)
>>>list_2
{1, 33, 3, 4, 77,88}
>>>print(list_1,type(list_1))#打印list_1类型,发现为set类型,证明为集合


b、取交集 intersectionlist_1  list_2共有的元素)

>>>list_1.intersection(list_2)    
{1, 3, 77}
>>> print(list_1  & list_2)
{1, 3, 77}
#上述两种方法均可以取出list_1与list_2的交集

c、取并集unionlist_1 list_2中全部去重元素)

>>>list_1.union(list_2)                 
{1, 33, 3, 4, 5,6, 12, 77, 88}
>>>list_1  | list_2
{1, 33, 3, 4, 5,6, 12, 77, 88}
#上述两种方法取两个集合的全部去重元素

d、取差集(差集是一个集合有,但是另一个集合没有的元素,所以差集可以得到两种不同的结果)

>>>list_1.difference(list_2) #list_1中存在但是list_2中不存在
{12, 5, 6}
>>>list_2.difference(list_1) ##list_2中存在但是list_1中不存在
{88, 33, 4}
>>> list_1 - list_2
{12, 5, 6}
>>> list_2 - list_1 
{88, 33, 4}

 基本操作:

 a、添加(集合操作没有插入动作,只能添加)

>>> list_1
{1, 3, 5, 6, 12,77}
>>>list_1.add(999)    #添加单项
>>>list_1.add(‘wang‘)
>>>list_1
{1, 3, 5, 6, 999,12, 77, ‘wang‘}
>>>list_1.update([‘alex‘,‘john‘,‘tom‘])  #添加多项
>>>list_1
{1, 3, 5, 6, 999,12, 77, ‘john‘, ‘tom‘, ‘wang‘, ‘alex‘}

b、删除

>>>list_1
{1, 3, 5, 6, 999,12, 77, ‘john‘, ‘tom‘, ‘wang‘, ‘alex‘}
>>>list_1.remove(999)  #通过remove方法删除,删除后不显示删除项,删除需要明确指定删除项的内容,因为集合是无序的,没有索引的概念
>>>list_1
{1, 3, 5, 6, 12,77, ‘john‘, ‘tom‘, ‘wang‘, ‘alex‘}
>>>list_1.remove(wang)  #针对字符串需要加引号
Traceback (mostrecent call last):
  File "<stdin>", line 1, in <module>
NameError: name ‘wang‘isnot defined
>>>list_1.remove(‘wang‘)
>>>list_1
{1, 3, 5, 6, 12,77, ‘john‘, ‘tom‘, ‘alex‘}
>>> list_1.pop()  #pop方法属于随机删除,删除后显示删除的内容
1
>>>list_1.pop()
3
>>>list_1.pop()
5
>>>list_1.pop()
6
>>>list_1.pop()
12
>>>list_1.pop()
77
>>>list_1.pop()
>>>list_1.pop()
‘john‘
>>>list_1
{‘tom‘, ‘alex‘}

cdiscard删除

>>>list_1
{‘wang‘, 1, 3, 5, 6, 999, 12, 77, ‘john‘, ‘tom‘, ‘alex‘}
>>>list_1.discard(999)  
>>>list_1
{‘wang‘, 1, 3, 5, 6, 12, 77, ‘john‘, ‘tom‘, ‘alex‘}
>>>list_1.discard(888)    #discard与remove的不同之处在于,discard如果是删除不存在的内容,不会报错,但是remove会报错
>>>list_1.remove(999)
Traceback (mostrecent call last):
  File "<stdin>", line 1, in <module>
KeyError: 999

d、长度len

>>>len(list_1)
10
>>>list_1
{‘wang‘, 1, 3, 5, 6, 12, 77, ‘john‘, ‘tom‘, ‘alex‘}

e、成员判断(in not in

>>>list_1
{‘wang‘, 1, 3, 5, 6, 12, 77, ‘john‘, ‘tom‘, ‘alex‘}
>>> ‘wang‘in list_1
True
>>> 11 in list_1     
False
>>> 11 notin list_1
True


 2、文件操作:

1、文件操作包括以下几种方式:

1)读模式

>>> data=http://www.mamicode.com/ open(‘yesterday.txt‘, ‘r‘)   #open函数默认是读默认,所以r可以省略,但是为了规范最好写清楚已哪种方式打开
>>> print(data)  #当打开这个文件后,print会返回该文件名字,默认与默认编码等文件本身属性
<_io.TextIOWrappername=‘yesterday.txt‘ mode=‘r‘ encoding=‘UTF-8‘>

2)写模式

>>> data=http://www.mamicode.com/ open(‘yesterday1.txt‘, ‘w‘)   #文件已写模式打开
>>>data.write(‘1234\n‘)   #当打开后,可以使用wirite方法进行写入操作,如果需要每行结束后换行,需要手动添加“\n”  这样保证在输入后进行换行操作,当写入后,会自动提示写了多少个字符
5
>>> f =data.read()    #由于模式之间不兼容,如果只以写模式打开文件,进行读操作会报错
Traceback (mostrecent call last):
  File "<stdin>", line 1, in <module>
io.UnsupportedOperation:not readable

3)追加模式

>>> data=http://www.mamicode.com/ open(‘yesterday1.txt‘, ‘a‘)  #和写模式不同,已追加模式打开文件,不会覆盖原文件内容,只会在文件后面进行添加,如果以w模式打开,会将文件原有内容全部清空,重新编写
>>>
>>>
>>>data.write(‘wwwyy\n‘)   #对于写与追加模式,都可以进行write操作
6
>>> f =data.read()    #追加模式也同样不能进行读操作
Traceback (mostrecent call last):
  File "<stdin>", line 1, in <module>
io.UnsupportedOperation:not readable


  总结:

文件打开最常用三种模式为读、写、追加。默认为open函数以读模式方式工作,在读模式中可以读取文件内容,写与追加模式均可以对文件进行修改,不同的是,读模式打开文件后,会将原有文件内容清空,添加新内容,而追加模式不会清空原有内容,会在文件最后添加新的需要追加的内容,至于如何在将rwa模式进行结合操作,会在修改文件时进行介绍

2、读模式的相关操作

1)read操作

>>> data= http://www.mamicode.com/open(‘yesterday.txt‘, ‘r‘)

>>>data.read()    #read操作会一次性将文件全部内容读取到内存中

‘往日重现\n\n当我年轻的时候\n听着收音机\n等待着我最喜爱的歌\n当它播放时我独自跟唱\n让我心情愉快起来\n\n就像那些快乐时光\n惊讶消失的无影无踪\n但当它们回来时\n就像是久没联络的朋友一样\n这都是我喜欢的歌\n\n每个Sha-la-la-la\n每个Wo-o-wo-o\n记忆依鲜明\n每个shing-a-ling-a-ling\n节奏依然美好\n\n当故事到了那个段落\n他伤了她的心\n让我流下泪来\n就像从前\n往日重现‘

>>>data.read()  # 由于文件指针的存在,当一次性读取文件到内存后如果不进行指针回退操作前再次读取,会返回空值,表示该内容上一次已经读取完毕,本次读取没有内容显示

2readline操作

>>> data= http://www.mamicode.com/open(‘yesterday.txt‘, ‘r‘)
>>>data.readline()  #与read操作一次性读取不同,readline操作每次只会读取一行内容存储到内存中,readline方法可以针对每行内容进行操作
‘往日重现\n‘
>>>data.readline()
‘\n‘
>>>data.readline()
‘当我年轻的时候\n‘
>>>data.readline()
‘听着收音机\n‘

3readlines操作

>>> data= http://www.mamicode.com/open(‘yesterday.txt‘, ‘r‘)
>>> data.readlines()#区别于read于readline操作,readlines操作也是一次性读取,不同的是它会将读取的内容放入到一个列表中,这样后续可以操作列表的方式对该文件内容进行需要的操作

4)close操作

>>>data.close()  #在r、w、a操作的最后需要将文件关闭,采用close方法进行关闭,这样才会将文件修改保存到硬盘中,如果没有关闭操作,默认情况下都是在内存中进行操作的

5)文件的编码格式

>>> data= http://www.mamicode.com/open(‘yesterday.txt‘, ‘r‘,encoding=‘utf-8‘) #在打开文件时需要跟文件的编码格式,python3中默认是采用utf-8格式的编码,所以可以省略
>>> print(data)
<_io.TextIOWrappername=‘yesterday.txt‘ mode=‘r‘ encoding=‘utf-8‘>

3、文件的其他操作

1encoding:打印文件编码

>>>data.encoding
‘utf-8‘

2)  fino()返回文件句柄所在操作系统的编码  基本不使用操作

3isatty()该文件是否是一个终端设备,linux系统中可以用来判断是否是一个tty文件

4name打印文件名称

>>>data.name
‘yesterday.txt‘

5)  seekable() 是否可以移动指针

>>>data.seekable()
True

6)  flush()刷新操作:

如果以写模式打开文件,写完后不一定立即写入磁盘,如果此时突然断电可能没有及时写入进文件,所以可以通过flush方法刷新进磁盘

例子:可以在安装程序时,打印进度条

import time,sys
for i in range(50):
   sys.stdout.write(‘#‘)
   sys.stdout.flush()  #将#号实时刷新到屏幕上来
   time.sleep(0.1)

7closed 判断文件是否关闭

>>>data.closed
False
>>>data.close()
>>>data.closed
True

8)  truncate()如果不写入任何东西就是清空文件

data.truncate(10)会只保留10个字节,其余的会删除,同时truncate自带文件指针,无论通过seek移到任何位置,truncate都会按照初始位置来删除与保留

 

4、修改文件:

  修改文件分为两种模式:

1、将文件全部读入内存中,然后修改,该方式典型代表就是vim程序

2、将文件按照行模式读,然后每行操作完毕后再放入新文件,这种方式节约内存占用,类似与sedawk操作

 

对于文件操作,除了典型r/w/a方式外还有其他操作,下面来简要介绍这几种更常用操作:

1r+  读写操作,表示又能读又能写,这个表示以读与追加模式开始,如果写,会将写的内容放入最后

2w+写读模式,创建新文件,输入内容,然后读取文件指针所在位置,在回退,再输入,会发现插入的内容,仍然在最后而不是通过seek调转

3a+追加读模式,在追加的过程中可以进行读

5、二进制文件

针对二进制文件有两种方式,rbwb,其中两种情况下使用rb

1、网络传输,socket传输时只能使用二进制格式编码

2、视频文件打开,也必须使用二进制格式打开

6with语句

为了避免打开文件后忘记关闭,可以通过with来管理上下文,即:

>>> withopen(‘tes2.txt‘,‘w‘) as f:f.write(‘nnnnn\n‘)
...

如此方式,当with代码执行完毕后,内部会自动关闭并释放文件所在内存,同时也可以同时打开多个文件

with open(‘tes2.txt‘,‘w‘) as f, open(‘test3.txt‘,‘w‘) as f2:#两个文件之间用‘,’来分割
    f.write(‘nnn\n‘)
    f2.write(‘mmmm\n‘)

 

3、字符编码与转码

知识点:

1.python2默认编码是ASCII, python3里默认是unicode

2.unicode 分为 utf-32(4个字节),utf-16(占两个字节)utf-8(1-4个字节) so utf-16就是现在最常用的unicode版本,不过在文件里存的还是utf-8,因为utf8省空间

3.py3encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string

在介绍编码之前先介绍下计算机语言与人类可识别语言转换:

计算机只能识别二进制编码,即01,在二进制编码中采用bit(位)来表示,但是这种方式对人类来讲是不可读的,所以初始阶段,发明了ASII码,即采用一个byte8bits)方式来表示人类可识别字母,28次方-1也就是使用255ASII码来表示A-Za-z0-9这些数字与字母,但是对于非英语国家来说,255个字符表示没法完全表示自己本国语言,对于中国来说,本身采用了gbk  gbk2308 gbk2312等编码方式来进行特定的编码,但是这种方式到了其他国家由于编码格式未统一,所以导致本国的程序到其他国家未必会被采用,基于这种情况,标注化组织开发了unicode即万国码的方式来代替了原有的各自为政的局面,unicode要求:最少已2个资金来表示,这样又引入了新的问题,就是比较浪费资源,所以最后统一使用utf-8编码方式:英语国家采用ASII编码,一个字节,欧洲等国家采用两个字节,而中国这种亚洲国家采用3个字节来表示自己的编码,至此解决了编码方式的问题

在说的编码与解码,由于类似bgkutf-8之间没法直接转换,都需要经过unicode作为中转编码,所以需要编码与解码过程

import sys
print(sys.getdefaultencoding())   #打印得出默认编码为utf-8
utf-8
s = ‘你好‘      #在python3中默认编码为unicode
s_gbk = s.encode(‘gbk‘)  #由于默认编码为unicode,所以这里从unicode到gbk编码采用的是encode模式,因为unicode没有decode过程了,可以直接encode
print(s_gbk)  #这里输出为gbk编码格式
b‘\xc4\xe3\xba\xc3‘
s_to_utf8 =s.encode(‘gbk‘).decode(‘gbk‘).encode(‘utf-8‘)  ‘‘‘从bgk变为utf-8:需要先把编码encode为bgk,然后在解码decode,解码是告诉自己为bgk,这时已经转换为unicode了,再从unicode状态encode成utf-8‘‘‘
print(s_to_utf8)
b‘\xe4\xbd\xa0\xe5\xa5\xbd‘
s_to_unicode =s.encode(‘gbk‘).decode(‘gbk‘).encode(‘utf-8‘).decode(‘utf-8‘)  #在上面的基础上再使用decode模式解码到unicode
print(s_to_unicode)
你好


4、函数

1、编程方式

1)面向对象:类  定义用class

2)面向过程:过程,定义用def

3)函数式编程:函数,定义用def

      其中函数式编程,其中没有任何变量,对于某一输入一定存在确定的输出,这种编程语言包括Lisprelang,这里对函数式编码不做过多讨论

2、定义函数

def func1():   #通过def方式定义函数
  ‘‘‘testing‘‘‘
  print(‘func1‘)
  return 0   #函数可以有返回值
 
a = func1()   #调用该函数

3、定义过程

def func2():  #定义过程与定义函数的区别在于定义过程是没有返回值的
    ‘‘‘testing‘‘‘
    print(‘in the func2‘)

4、调用函数与调用过程,查看返回值

def func1():  
  ‘‘‘testing‘‘‘
  print(‘func1‘)
  return 0
 
def func2():
    ‘‘‘testing‘‘‘
    print(‘in the func2‘)
 
a = func1()  #调用函数1
b = func2() #调用过程2
 
print(a)
#打印返回值为0
print(b)
#打印没有返回值,按照默认来定义:None


5、使用函数的好处

1)代码的重复利用

2)程序容易扩展

3)保持代码的一致性

6、函数的返回值

def func1():
  ‘‘‘testing1‘‘‘
 
def func2():
    ‘‘‘testing2‘‘‘
    return 1
 
def func3():
    ‘‘‘testing3‘‘‘
    return 1,[1,2,3,4,5,6,7],(1,2,4,3,3,‘wang‘),{‘name‘:‘gavin‘,‘age‘:99}
 
a = func1()
b = func2()
c = func3()
 
print(a)
None
print(b)
1
print(c)
(1, [1, 2, 3, 4,5, 6, 7], (1, 2, 4, 3, 3, ‘wang‘), {‘age‘: 99, ‘name‘: ‘gavin‘})

    返回值个数=0,返回None,系统默认返回空

    返回值个数=1,反正object,定义哪个返回值,就返回哪个

    反正值个数>1,返回tuple,当返回值个数大于1时,返回一个元组包含哪些需要返回的数值

 7、形参与实参

def func1(x,y):  #x与y时函数的形参,在没有调用该函数时,x与y不代表任何变量,不占用内存
  ‘‘‘testing1‘‘‘
  x = x + y
  return x
 
 
a =func1(10,20)  #10与20是在调用该函数式传递给该函数的实参,目的是代替形参传入函数得到预期的结果
print(a)   #在没有默认参数的情况下,形参与实参是需要一一对应的,如果调用时不一一对应会导致报错
30

8、默认参数

def func1(x,y=20):#y有默认参数,但是实际调用时没有实参对y赋值,y将采用默认参数,需要注意的是,默认参数要放在最后


def func1(x,y=20):#y有默认参数,但是实际调用时没有实参对y赋值,y将采用默认参数,需要注意的是,默认参数要放在最后
  ‘‘‘testing1‘‘‘
  x = x + y
  return x
a = func1(10)
print(a)
30
b = func1(11,21)
print(b)
32

  默认参数特点:

调用函数时,默认参数可有可无,默认参数的用途是1在默认安装软件时使用,2在连接数据库端口号时使用

9、局部变量与全局变量

  局部变量只在函数中生效,而全部变量是在整个程序中都生效的变量,代码顶层定义的变量,局部变量变成全局变量需要在函数中global这个局部变量,但是千万不要这么使用,但是需要注意的是,列表、字典、集合、类都是可以在函数中修改内容的,字符串与整数在局部变量中不能修改

name = ‘gavin‘
 
def my(name,age):
    name = ‘jack‘   #局部变量
    age = 23
    return name,age
 
 
a =my(name,44)   #name的局部变量在函数中生效变为jack,但是函数结束后仍然为gavin这个全局变量
print(a)   #传入的44在函数中没有生效
(‘jack‘, 23)
print(type(a))  #返回值多于一个,反正的是tuple
<class ‘tuple‘>
print(a[0])  #可以按照元组方式调用返回值
jack
print(a[1])
23
print(name)
gavin


a = ‘gavin‘
 
def my(name):
    global a    #将a变为全局变量
    name = ‘jack‘   #局部变量
    a = ‘john‘
    print(name,a)
 
my(‘a‘)
jack john
print(a)
john
names = [‘alex‘,‘gavin‘,‘tom‘]
 
def my():
    print(names)
    names[1] = ‘jack‘   #将全局变量中的names[1]修改为jack
    return names
 
my()
[‘alex‘, ‘gavin‘, ‘tom‘]
print(names)  #在打印时发现局部变量中的jack替换了全部变量中的gavin
[‘alex‘, ‘jack‘, ‘tom‘]

10、递归

在函数内部,可以调用其他函数,如果一个函数在内部调用函数本身,这个函数就叫做递归函数

  递归的特点:

1)必须有一个明确的结束条件

2)每次进入更深的一层递归时,问题规模相比上一次递归应有所减少

3)递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈这种数据结构实现的,每当进入一个函数调用,栈会增加一层栈帧,每当函数返回会减少一层栈帧,由于栈的大小不是无限的,所以递归次数过多会导致栈的溢出)

def calc(n):
   print(n)
   if int(n/2) > 0:
       returncalc(int(n/2))
   print(‘--->‘, n)
calc(10)
10
5
2
1
---> 1

11、高阶函数

变量可以指向函数,函数的参数能接受变量,那么一个函数就能接收另一个函数作为参数,这种函数叫做高阶函数

def add(a,b,f):
   return f(a) + f(b)
res =add(3,-10,abs)
print(res)
13


第三周总结