Python自学,Day3Python基础

本节内容

  1. 集合操作
  2. 文件操作
  3. 字符编码与转码
  4. 函数基本语法及特性
  5. 参数与局部变量
  6. 返回值
  7. 嵌套函数
  8. 递归
  9. 匿名函数
  10. 函数式编程介绍
  11. 高阶函数
  12. 内置函数

1、集合                                             

集合是一个无序的,不重复的数据组合,它的主要作用如下:

  • 去重,把一个列表变成集合,可以自动去重
  • 关系测试,测试两组数据之前的交集、差集、并集等关系

常见操作

  • 定义集合
 1 #创建一个数值集合
 2 num=set([1,2,3,4])
 3 print("1:",num)
 4 
 5 #创建一个唯一字符的集合
 6 str=set("hello")
 7 print("2:",str) #按无重复的字母单独拆开
 8 
 9 #数值和字符多种形式
10 name=set(["ace",1,3,5])
11 print("3:",name)
12 
13 #输出结果
14 1: {1, 2, 3, 4}
15 2: {'l', 'e', 'o', 'h'}
16 3: {3, 1, 'ace', 5}
  • 关系测试
num=set([1,2,3,4])
name=set(["ace",1,3,5])
str=set([1,3])

#并集
print("1:",num.union(name)) #关键词表示形式
print("2:",num|name) #运算符表示

#交集
print("3:",num.intersection(name))
print("4:",num&name)

#差集
print("5:",num.difference(name))    #在num中,但不在name中
print("6:",num-name)

#子集
print("7:",str.issubset(name)) #完全包含则为子集
print("8:",str<=name)

#父集
print("8:",name.issuperset(str))
print("9:",name>=str)

#对称差集
print("10:",num.symmetric_difference(name)) #在num或name中,但是不会同时出现在二者中
print("11:",num^name)

#不存在交加
print("12:",num.isdisjoint(name))  #当两者间无交集时,则返回true,否则false

#输出结果
1: {1, 2, 3, 4, 5, 'ace'}
2: {1, 2, 3, 4, 5, 'ace'}
3: {1, 3}
4: {1, 3}
5: {2, 4}
6: {2, 4}
7: True
8: True
8: True
9: True
10: {2, 4, 5, 'ace'}
11: {2, 4, 5, 'ace'}
12: False
  • 增删改
 1 num=set([1,2,3,4])
 2 name=set(["ace",1,3,5])
 3 str=set([1,3])
 4 
 5 #添加单项
 6 num.add(5)
 7 print("1:",num)
 8 
 9 #添加多项
10 str.update(["shang",2,4])
11 print("2:",str)
12 
13 #删除指定项
14 name.remove(1) #当删除项不存在时,会报错
15 print("3:",name)
16 
17 #随机删除,并将删除项输出
18 print("4:",name.pop())
19 
20 #删除指定项
21 name.discard(3) #当但删除项不存在时,程序不处理
22 print("5:",name)
23 
24 #输出结果
25 1: {1, 2, 3, 4, 5}
26 2: {1, 2, 3, 4, 'shang'}
27 3: {'ace', 3, 5}
28 4: ace
29 5: {5}

2、文件操作                                    

对文件操作流程

  1. 打开文件,得到文件句柄并赋值给一个变量
  2. 通过句柄对文件进行操作
  3. 关闭文件
  • 创建文件

先创建file文件,格式为Text,在Text文件中添加内容

文件:over_the_sea

内容:为你我用了半年的积蓄

漂洋过海来看你
为了这次相聚
连见面时的呼吸
都曾反复练习
  • 读取文件
 1 f=open("over_the_sea",'r',encoding="utf-8") #需要转化成utf-8
 2 data=f.read() #文件句柄
 3 print(data)
 4 
 5 #输出结果
 6 为你我用了半年的积蓄
 7 漂洋过海来看你
 8 为了这次相聚
 9 连见面时的呼吸
10 都曾反复练习

备注:

打开文件的操作:open("文件名",'模式',encoding="转移字符格式")

r为只读模式,为默认模式,可以不定义;

f.read()为文件的读取

  当多次读取时

f=open("over_the_sea",'r',encoding="utf-8") #需要转化成utf-8
data=f.read() #文件句柄
print(data)
data2=f.read()
print('---------data2---------',data2)

#输出结果
为你我用了半年的积蓄
漂洋过海来看你
为了这次相聚
连见面时的呼吸
都曾反复练习
---------data2--------- 

备注:从输出结果可以看出,data2无内容;

因read的模式为影响到读取文件的指针(可类比C语言中的指针),data读取完成后,指针到文件的最后位置,data2进行read时,后续无内容,所以data2无数据

  • 写文件
1 f=open("across_the_ocean_to_meet_you",'w',encoding="utf-8") #需要转化成utf-8
2 f.write("To meet you I’ve saved every penny\n"
3         "To travel far across the sea\n"
4         "To be free-and-easy\n"
5         "Many times I rehearsed the meet\n"
6         "Hoped to impress you deep\n"
7         )

结果:新增across_the_ocean_to_meet_you文件,文件内容为write中到内容;

文件内容:

To meet you I’ve saved every penny
To travel far across the sea
To be free-and-easy
Many times I rehearsed the meet
Hoped to impress you deep

写入的内容,以行为区分,换行时需用""来新定义文本内容

因w只是写的模式,不能读取;需注意,w的模式时新创建文件,当文件名已存在时,则会将原文件覆盖

  • 追加写文件(append)
 1 f=open("across_the_ocean_to_meet_you",'a',encoding="utf-8")
 2 data=f.write("Words said never convey what I wanted to say\n"
 3             "What in my mind so clearly\n")
 4 
 5 
 6 #文件内容
 7 To meet you I’ve saved every penny
 8 To travel far across the sea
 9 To be free-and-easy
10 Many times I rehearsed the meet
11 Hoped to impress you deep
12 Words said never convey what I wanted to say
13 What in my mind so clearly

备注:模式a,为在原文件的基础上追加内容,当不存在指定文件时,则会同w模式一样创建原文件,并追加内容

  • 按行读取
1 f=open("across_the_ocean_to_meet_you",'r',encoding="utf-8")
2 
3 print(f.readlines())    #按行进行全部读取,并输出打印
4 
5 #输出结果
6 ['To meet you I’ve saved every penny\n', 'To travel far across the sea\n', 'To be free-and-easy\n', 'Many times I rehearsed the meet\n', 'Hoped to impress you deep\n', 'Words said never convey what I wanted to say\n', 'What in my mind so clearly\n']

备注:输出结果为列表

  打印前5行

f=open("across_the_ocean_to_meet_you",'r',encoding="utf-8")

#打印前5行
for line in range(5):
    print(f.readline())#readline为按行读取

#输出结果
To meet you I’ve saved every penny

To travel far across the sea

To be free-and-easy

Many times I rehearsed the meet

Hoped to impress you deep

  按行打印全部行

 1 f=open("across_the_ocean_to_meet_you",'r',encoding="utf-8")
 2 
 3 for line in f.readlines():
 4     print(line)
 5 
 6 #输出结果
 7 
 8 To meet you I’ve saved every penny
 9 
10 To travel far across the sea
11 
12 To be free-and-easy
13 
14 Many times I rehearsed the meet
15 
16 Hoped to impress you deep
17 
18 Words said never convey what I wanted to say
19 
20 What in my mind so clearly

备注:readlines为按行读取后的列表,通过循环列表来按行打印

  优化:因文件中有回车,所以输出结果中有空格,去掉空格,使用strip()

print(line.strip())

  第四行不打印

f=open("across_the_ocean_to_meet_you",'r',encoding="utf-8")
data=f.readlines()
for line in data:
    if data.index(line)==3:
        print("------我是分隔符------")
        continue
    print(data.index(line),line.strip())

#输出结果
0 To meet you I’ve saved every penny
1 To travel far across the sea
2 To be free-and-easy
------我是分隔符------
4 Hoped to impress you deep
5 Words said never convey what I wanted to say
6 What in my mind so clearly

  另外一种操作

1 f=open("across_the_ocean_to_meet_you",'r',encoding="utf-8")
2 
3 for index,line in enumerate(f.readlines()): #enumerate获取下标
4     if index==3:
5         print("------我是分隔符------")
6         continue
7     print(index,line.strip())

备注:输出结果与上一种方法相同

  readlines的缺点:一次性将文件的内容全部读取到内存中,若文件量太大,会造成内存占用过高

  改进方法:读取一行打印之后,读取下一行内容,将上一行内容覆盖,所以以上方法尽量不用

  高效的循环方法

 1 f=open("across_the_ocean_to_meet_you",'r',encoding="utf-8")
 2 
 3 count=0 #用于记录打印行数
 4 for line in f:
 5     if count==3:
 6         print("------我是分隔符------")
 7         count+=1
 8         continue
 9     print(line.strip())
10     count+=1
11 
12 
13 #输出结果
14 To meet you I’ve saved every penny
15 To travel far across the sea
16 To be free-and-easy
17 ------我是分隔符------
18 Hoped to impress you deep
19 Words said never convey what I wanted to say
20 What in my mind so clearly

  备注:该方法为一行一行读取,且后一行内容会覆盖前一行内容

  • tell()  当前read的指针所在的位置
  • seek()  设置指针所在的位置

  over_the_sea的文件内容

To meetyou I have saved every penny
To travel far across the sea
To be free-and-easy
Many times I rehearsed the meet
f=open("over_the_sea",'r',encoding="utf-8") #需要转化成utf-8
data=f.readline() #文件句柄
print(data.strip())
print(f.tell()) #获取当前指针的位置
f.seek(0)   #将指针指向最初始0的位置
print(f.readline())

#输出结果
To meetyou I have saved every penny
36
To meetyou I have saved every penny

备注:tell()是按照一个字符为一个位置设定,所以打印的为“36”

  • flush  

  用来将写入缓存的内容强制写入磁盘中

 1 import sys,time
 2 
 3 for i in range(20):
 4     sys.stdout.write("#")   #屏幕作为终端输出
 5     sys.stdout.flush()  #强制刷新到磁盘
 6     time.sleep(0.1) #睡眠0.1秒
 7 
 8 #输出结果
 9  ####################
10 
11 #备注:依次输出#
  • truncate  截断
1 f=open("across_the_ocean_to_meet_you",'a',encoding="utf-8")
2 
3 f.truncate(10) 

  从第一个字符开始,到第10个字符进行截断

  截断之后文件内容

To meet yo
  • r+ 读写(读和追加的模式)
 1 f=open("across_the_ocean_to_meet_you",'r+',encoding="utf-8") #r+的模式
 2 
 3 print(f.readline().strip())
 4 print(f.readline().strip())
 5 print(f.readline().strip())
 6 f.write("------第四行追加-------")
 7 print("-------分隔符---------")
 8 print(f.read())
 9 
10 #输出结果
11 To meet you I’ve saved every penny
12 To travel far across the sea
13 To be free-and-easy
14 -------分隔符---------
15 Many times I rehearsed the meet
16 Hoped to impress you deep
17 Words said never convey what I wanted to say
18 What in my mind so clearly------第四行追加-------

备注:及时打印为前三行之后,指针在第四行,但是执行write的操作时,却从最后开始追加

  • w+ 写读(先创建文件,然后可进行读和写的操作-使用场景不多)
 1 f=open("across_the_ocean_to_meet_you",'w+',encoding="utf-8") #r+的模式
 2 
 3 print(f.readline().strip())
 4 print(f.readline().strip())
 5 print(f.readline().strip())
 6 f.write("------第四行追加-------")
 7 print("-------分隔符---------")
 8 print(f.read())
 9 
10 #输出结果
11 
12 
13 
14 -------分隔符---------
15 28

备注:1个汉字相当于5个字符,所以输出字符为28;因先进行创建文件,所以前三个读都为空;执行完写之后,指针在最后位置,所以最后读取的内容也为空

  •  a+ 追加读写
 1 f=open("across_the_ocean_to_meet_you",'a+',encoding="utf-8") #r+的模式
 2 
 3 print(f.readline().strip())
 4 print(f.readline().strip())
 5 print(f.readline().strip())
 6 f.write("\n------我是添加项-------")
 7 print("-------分隔符---------")
 8 f.seek(0)
 9 print(f.read())
10 
11 #输出结果
12 
13 
14 
15 -------分隔符---------
16 To meet you I’ve saved every penny
17 To travel far across the sea
18 To be free-and-easy
19 Many times I rehearsed the meet
20 Hoped to impress you deep
21 Words said never convey what I wanted to say
22 What in my mind so clearly
23 ------我是添加项-------

备注:追加读写,是将指针直接定位在最后,所以前三行读取的内容为空;追加内容添加在最后,添加完之后,指针也在最后;此时将指针的位置设定为0的位置,可以读取整个文件

  •  修改文件内容

要求:修改文件中的指定信息,并将信息保存至新文件中

1 #需求:修改文件中信息,并将信息保存至新文件中
2 
3 f=open("across_the_ocean_to_meet_you","r",encoding="utf-8")
4 f_new=open("across_the_ocean_to_meet_you.bak","w",encoding="utf-8")#创建新文件
5 
6 for line in f:
7     if "across the sea" in line:
8         line=line.replace("across the sea","across the ocean") #使用字符串修改
9     f_new.write(line) #不管是否是需要更新的文件,都是将line更新至至新文件

采用的使逐行读取校验,如果不是需要更改的内容项,则直接更新至新文件,如果是需要更改的内容项,则使用字符替换,然后再写入新的文件中

  • with操作

正常情况下,在打开文件操作后,需关闭该文件,关闭语句为:f.close();通常在程序执行完之后,python会自动给关闭打开的文件

但是会存在忘记关闭的情况,尤其在程序执行时,可能会同时打开多个文件,以及大量暂用内存;

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

1 with open("文件名","r",encoding="utf-8") as f:
2     ...
3     ...
4     ...

如此方式,当with代码块执行完毕之后,内部会自动关闭并释放文件资源。

以修改文件内容的场景为例:

1 with open("across_the_ocean_to_meet_you","r",encoding="utf-8") as f ,\
2      open("across_the_ocean_to_meet_you.bak","w",encoding="utf-8") as f_new:
3     for line in f:
4         if "across the sea" in line:
5             line = line.replace("across the sea", "across the ocean")  # 使用字符串修改
6         f_new.write(line)
  • 总结

  打开文件的模式有:

  • r ,只读模式【默认】
  • w,只写模式【不可读;不存在则创建;存在则清空内容;】
  • x, 只写模式【不可读;不存在则创建,存在则报错】
  • a, 追加模式【可读;   不存在则创建;存在则只追加内容;】

"+" 表示可以同时读写某个文件

  • r+, 读写【可读,可写】
  • w+,写读【可读,可写】
  • x+ ,写读【可读,可写】
  • a+, 写读【可读,可写】

 "b"表示以字节的方式操作

  • rb  或 r+b
  • wb 或 w+b
  • xb 或 w+b
  • ab 或 a+b

 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型

 3、字符编码及转码                                      

详细文章:

http://www.cnblogs.com/yuanchenqi/articles/5956943.html

http://www.diveintopython3.net/strings.html

yy:找时间在看吧,先抓重点快速前进....

需知:

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

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

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

  decode() 编码成unicode

  encode() 解码成utf-8,或者gbk

#-*-coding:gbk-*-
#声明文件的编码格式为gbk
#备注:文件格式调整为GBK的模式

import sys
print(sys.getdefaultencoding()) #系统默认的编码还是utf-8


s="你好" #仍然为utf-8
print(s)
print(s.encode("gbk")) #显示的是gbk的编码格式
print(s.encode("utf-8"))
print(s.encode("utf-8").decode("utf-8"))
print(s.encode("gb2312"))#gbk向下兼容gb2312
print(s.encode("gb2312").decode("gb2312"))

 4、函数与函数式编程                                    

  python定义函数

  def 函数名(参数):

    "文档描述"

    函数体逻辑

    return 参数

 1 #函数式编程
 2 def fun(x):
 3     '''自增函数'''
 4     x+=1
 5     print(x)
 6     return x
 7 
 8 #面向过程(无返回值的函数)
 9 def fun2(x):
10     '''过程'''
11     print(x)
12 
13 x=fun(1)
14 y=fun2(1)
15 
16 print("x:",x) #x有具体的返回值
17 print("y:",y) #y返回为none
18 
19 
20 #输出结果
21 2
22 1
23 x: 2
24 y: None

 函数例子:

import time

def logger(): #打印log日志
    time_format='%Y-%m-%d %X' #定义时间格式
    time_current=time.strftime(time_format) #获取当前时间
    with open("log.txt","a+") as f:
        f.write("%s error.log\n" %time_current)


def test1():
    print("in the test1")
    logger()

def test2():
    print("in the test2")
    logger()

def test3():
    print("in the test3")
    logger()

test1()
test2()
test3()

#输出结果
in the test1
in the test2
in the test3


#log.txt文件内容
2018-08-16 07:01:02 error.log
2018-08-16 07:01:02 error.log
2018-08-16 07:01:02 error.log

使用函数的优点总结:

1、代码重用

2、保持一致性

3、可扩展性

  • 返回值return
def test1():
    print("in the test1")

def test2():
    print("in the test2")
    return 0

def test3():
    print("in the test3")
    return 1,'hello',['shang','quan'],{'shang','quan'}

x=test1() #x用来接收返回值
y=test2()
z=test3()

print(x)    #返回none
print(y)    #返回0
print(z)    #返回元组


#输出结果
in the test1
in the test2
in the test3
None
0
(1, 'hello', ['shang', 'quan'], {'shang', 'quan'})

总结:

返回值个数=0,none

返回值个数=1,定义的内容

返回值个数>1,元组

  • 参数定义
def test(x,y): #x、y为形参
    print(x)
    print(y)

test(1,2) #1,2为实参(位置参数)
test(y='A',x='B') #关键字调用
test(5,y=7) #关键字一定不可以放在位置参数前

#输出结果
1
2
B
A
5
7

  默认参数

   调用函数时,使用默认函数

 1 def test(x,y=2):
 2     print(x)
 3     print(y)
 4 
 5 
 6 test(1)
 7 test(1,3)
 8 test(1,y=4)
 9 
10 #输出结果
11 1
12 2
13 1
14 3
15 1
16 4

默认阐述特点:调用函数的时候,默认参数非必须传递

用途:软件默认安装、数据库端口号等

  参数组

当实参不固定时,需使用参数组传递

def test(x,*args):  #
    print(x)
    print(args)

test(1,2,3,4,5)

#输出结果
1
(2, 3, 4, 5)

不固定参数,使用*args传递,将接收到的参数转化成元组的方式

备注:*args是用来接受N个位置参数

 字典的方式

 1 #字典  把N个关键字参数,转换成字典的方式
 2 def test2(**kwargs):
 3     print(kwargs)
 4 
 5 test2(names='shang',age=29,sex='M')
 6 
 7 def test3(name,**kwargs):
 8     print(name)
 9     print(kwargs)
10 
11 test3('shang',age=29,sex='M')
12 
13 def test4(name,age=19,**kwargs):
14     print(name)
15     print(age)
16     print(kwargs)
17 
18 test4('shang',sex='M',hobby='Make Money')
19 
20 
21 #输出结果
22 {'names': 'shang', 'age': 29, 'sex': 'M'}
23 shang
24 {'age': 29, 'sex': 'M'}
25 shang
26 19
27 {'sex': 'M', 'hobby': 'Make Money'}

组合的方式

 1 def test1(name,age=19,*args,**kwargs):
 2     print(name)
 3     print(age)
 4     print(args)
 5     print(kwargs)
 6 
 7 test1('shang',29,'ace','python',10,sex='M',hobby='Make Money')
 8 
 9 
10 #输出结果
11 shang
12 29
13 ('ace', 'python', 10)
14 {'sex': 'M', 'hobby': 'Make Money'}

备注:位置参数传递给*args,如果没有对应的位置参数,则args为空元组;关键字传递给**kwargs

  • 局部变量

定义在函数中,该函数是局部变量的作用域

 1 def chang_name(name):
 2     print("before_name",name)
 3     name='ace'  #局部变量,只在函数中生效
 4     print("after_name",name)
 5 
 6 
 7 name='shang'
 8 chang_name(name)
 9 print(name)
10 
11 #result
12 before_name shang
13 after_name ace
14 shang
  • 全局变量

在整个程序中都生效的变量,定义在程序的顶部部分

 1 name='shang'  #全局变量
 2 age=29 #全局变量
 3 
 4 def chang_name(name):
 5     global age  #声明全局变量
 6     age = 30  # 修改全局变量
 7     print("before_name",name)
 8     name='ace'  #局部变量,只在函数中生效
 9     print("after_name",name)
10 
11 chang_name(name)
12 print(name)
13 print(age)
14 
15 #result
16 before_name shang
17 after_name ace
18 shang
19 30

备注:全局变量理论上是不可以修改的,但是如果需要修改的场景,则需在函数中先声明全局变量global,然后就可以改动全局变量;

同时,不可在函数中用global定义全局变量,不符合书写规范

需注意

当全局变量为:列表、字典、集合时,函数可以直接修改全局变量

 1 resume=['shang',29,'pm']
 2 
 3 def change_resume():
 4     resume[1]=30 #函数中可以直接修改列表、字典、集合和类的全局变量中的参数
 5     
 6 change_resume()
 7 print(resume)
 8 
 9 #result
10 ['shang', 30, 'pm']
  • 递归

在函数内部,可以调用其他函数,如果一个函数在内部调用自己,这个函数就是递归函数

递归特征:

1、必须要有明确的结束条件

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

3、递归效率不高,递归层次过多会导致栈溢出

 1 def calc(n):
 2     print(n)
 3     n=int(n)
 4     if n > 1:
 5         return calc(n/2)
 6 
 7 n=input('input the number')
 8 calc(n)
 9 
10 #result
11 input the number45
12 45
13 22.5
14 11.0
15 5.5
16 2.5
17 1.0
  •  高阶函数

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

1 def sum(x,y,func):
2     return func(x)+func(y)
3 
4 add=sum(3,-1,abs)   #将绝对值函数abs传递给func
5 print(add)
6 
7 #result
8 4

   

原文地址:https://www.cnblogs.com/ace722/p/9446701.html