python基础之高阶函数,读写文件,常用模块,字符编码

一. 三元运算,filter和map与lambda表达式结合使用举例

1、三元运算

  • 三元运算格式: result=值1 if x<y else 值2 if条件成立result=1,否则result=2
  • 作用:三元运算,又称三目运算,主要作用是减少代码量,是对简单的条件语句的缩写

三元运算:

name = 'Tom' if 1 == 1 else 'fly'
print(name)
# 运行结果: Tom

三元运算与lambda结合:

f = lambda x:x if x % 2 != 0 else x + 100
print(f(10))                    # 110

2、lambda基本使用

  • lambda只是一个表达式,函数体比def简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda表达式是起到一个函数速写的作用。允许在代码内嵌入一个函数的定义。
  • 格式:lambda的一般形式是关键字lambda后面跟一个或多个参数,紧跟一个冒号,之后是一个表达式。

lambda基本使用:

f = lambda x,y,z:x+y+z
print(f(1,2,3))                    # 6

my_lambda = lambda arg : arg + 1
print(my_lambda(10))               # 11

3、总结:filter()和map()函数区别

  • Filter函数用于对序列的过滤操作,过滤出需要的结果,一次性返回他的过滤设置于的是条件
  • Map函数是对序列根据设定条件进行操作后返回他设置的是操作方法,无论怎样都会返回结果

4、filter与lambda表达式结合使用

filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。

  • 1 filter()函数可以对序列做过滤处理,就是说可以使用一个自定的函数过滤一个序列,把序列的每一项传到自定义
    的过滤函数里处理,并返回结果做过滤。最终一次性返回过滤后的结果。

  • 2 . filter()函数有两个参数:
    • 第一个,自定函数名,必须的
    • 第二个,需要过滤的列,也是必须的

利用 filter、lambda表达式 获取l1中元素小于33的所有元素 l1 = [11, 22, 33, 44, 55]:

l1= [11,22,33,44,55]
a = filter(lambda x: x<33, l1)
print(list(a))

自定义函数代替lambda实现相同功能:

l1= [11,22,33,44,55]
def func(num):
    if num>33:
        return num
result=filter(func,l1)
print(list(result))

5、map与lambda表达式结合使用

map()是 Python 内置的高阶函数,它接收一个函数 f 和一个list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。**
map使用:第一个参数接收一个函数名,第二个参数接收一个可迭代对象

map最基本使用:

lt = [1, 2, 3, 4, 5, 6]
def add(num):
    return num + 1
rs = map(add, lt)
print(list(rs))           #运行结果:  [2, 3, 4, 5, 6, 7]

利用map,lambda表达式将所有偶数元素加100:

l1= [11,22,33,44,55]
ret = map(lambda x:x if x % 2 != 0 else x + 100,l1)
print(list(ret))
# 运行结果: [11, 122, 33, 144, 55]

利用map,lambda表达式将所有偶数元素加100:

l1= [11,22,33,44,55]
def add(num):
    if num%2 == 0:
        return num
    else:
        return num + 100
rs = map(add, l1)
print(list(rs))

自定义函数代替lambda实现相同功能:

l1= [11,22,33,44,55]
def add(num):
    if num%2 == 0:
        return num
    else:
        return num + 100
rs = map(add, l1)
print(list(rs))

6、reduce函数

reduce()函数也是Python内置的一个高阶函数。reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。

  • reduce()函数即为化简函数,它的执行过程为:每一次迭代,都将上一次的迭代结果与下一个元素一同传入二元func函数中去执行。
  • 在reduce()函数中,init是可选的,如果指定,则作为第一次迭代的第一个元素使用,如果没有指定,就取seq中的第一个元素。

使用reduce进行求和运算:

在这里插入代码片复制代码
from functools import reduce
def f(x, y):
 return x + y

print(reduce(f, [1, 3, 5, 7, 9]))  # 25
# 1、先计算头两个元素:f(1, 3),结果为4;
# 2、再把结果和第3个元素计算:f(4, 5),结果为9;
# 3、再把结果和第4个元素计算:f(9, 7),结果为16;
# 4、再把结果和第5个元素计算:f(16, 9),结果为25;
# 5、由于没有更多的元素了,计算结束,返回结果25。

print( reduce(lambda x, y: x + y, [1, 3, 5, 7, 9])  )  # 25

使用reduce将字符串反转:

'''使用reduce将字符串反转'''
s = 'Hello World'
from functools import reduce

result = reduce(lambda x,y:y+x,s)
# 1、第一次:x=H,y=e  => y+x = eH
# 2、第二次:x=l,y=eH  => y+x = leH
# 3、第三次:x=l,y=leH  => y+x = lleH
print( result )      # dlroW olleH

7、sorted函数

功能:对所有可迭代的对象进行排序操作
1)sorted和sort区别

  • sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
  • sort 是对已经存在的列表进行操作,无返回值,而 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

2)sorted使用

sorted 语法:sorted(iterable, cmp=None, key=None, reverse=False)

iterable -- 可迭代对象。
cmp -- 比较的函数
key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。

sorted对列表排序:

students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
print( sorted(students, key=lambda s: s[2], reverse=False) )    # 按年龄排序
# 结果:[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

sorted对字典排序:

d = {'k1':1, 'k3': 3, 'k2':2}
# d.items() = [('k1', 1), ('k3', 3), ('k2', 2)]
a = sorted(d.items(), key=lambda x: x[1])
print(a)            # [('k1', 1), ('k2', 2), ('k3', 3)]

二. 读写文件

  • read(): 指定读取指定大小的文件(默认一次读取所有)
  • readline(): 逐行读取,适合读大文件
  • readlines(): 一次性读取所有文件, 将文件按行读取成列表

1、open函数用来打开文件

1. open(name[, mode[, buffering]]) 打开文件可传的参数

  • open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象。
  • 模式(mode)和缓冲(buffering)参数都是可选的

2. 打开文件的模式有

      • r,只读模式(默认)。
      • w,只写模式。【不可读;不存在则创建;存在则删除内容;】
      • a,追加模式。【可读; 不存在则创建;存在则只追加内容;】

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

      • w,只写模式。【不可读;不存在则创建;存在则删除内容;】
      • w+,写读

      • a+,同a

3、with语句

作用:将打开文件写在with中当对文件操作完成后with语句会自动帮关闭文件,避免忘记写f.close()

with读文件:

with open("data1.txt",'r',encoding = 'utf-8') as f:
    for line in f:
        print(line)

2、三种读操作比较

  • readline()每次读取一行,当前位置移到下一行
  • readlines()读取整个文件所有行,保存在一个列表(list)变量中,每行作为一个元素
  • read(size)从文件当前位置起读取size个字节,如果不加size会默认一次性读取整个文件(适用于读取小文件)

三种读操作举例:

#1. read()一次读取所有内容
'''aaa111
bbb222'''
f = open(r"data.txt")
print(f.read())
f.close()

#2. readline(),每次只读取一行,光标下移
'''
0: aaa111

1: bbb222
'''
f = open(r"data.txt")
for i in range(2):
    print(str(i) + ": " + f.readline(),)

#3. 一次读取所有,每行作为列表的一个值
'''['aaa111\n', 'bbb222\n']'''
f = open(r"data.txt")
print(f.readlines())

3、使用read()读文件

1. read(n)读取指定长度的文件

read读取指定长度字符串:

f = open(r"somefile.txt")
print(f.read(7))        # Welcome        先读出 7 个字符
print(f.read(4))        #‘ to ‘                接着上次读出 4 个字符
f.close()

2. seek(offset[, whence]) 随机访问

作用:从文件指定位置读取或写入

从指定位置写入:

f = open(r"somefile.txt", "w")
f.write("01234567890123456789")
f.seek(5)
f.write("Hello, World!")
f.close()
f = open(r"somefile.txt")
print(f.read())                 # 01234Hello, World!89

3. tell 返回当前读取到文件的位置下标

返回读取位置下标:

f = open(r"somefile.txt")
f.read(1)
f.read(2)
print(f.tell())             # 3     3就是读取到文件的第三个字符

4、readline()读文件

作用:readline 的用法,速度是fileinput的3倍左右,每秒3-4万行,好处是 一行行读 ,不占内存,适合处理比较大的文件,比如超过内存大小的文件

readline读取大文件:

f1 = open('test02.py','r')
f2 = open('test.txt','w')
while True:
    line = f1.readline()
    if not line:
        break
    f2.write(line)
f1.close()
f2.close()

5、readlines()读文件

作用:readlines会把文件都读入内存,速度大大增加,但是木有这么大内存,那就只能乖乖的用readline

readlines读文件:

f1=open("readline.txt","r")
for line in f1.readlines():
    print(line)

6、将data1.txt中内容读取并写入到data2.txt中

将data1.txt内容读取到data2.txt:

f1 = open('data1.txt','r')
f2 = open('data2.txt','w')

for line in f1:
    f2.write(line)

f1.close()
f2.close()

7、使用eval()方法将文件读取成字典

将文件读取成字典:

f = open('data1.txt')
f1 = (f.read())
data = eval(f1)
f.close()
print(data)         # 运行结果: {'k2': 'v2', 'k3': 'v3', 'k1': 'v1'}

8、将文件内容读取成列表

View Code:

lock = []
f = open("password.txt")
for name in f.readlines():
    lock.append(name.strip('\n'))
print(lock)
运行结果: ['aaa 111', 'bbb 222', 'ccc 333']

三. python常用模块之subprocess

subprocess模块是python从2.4版本开始引入的模块。主要用来取代 一些旧的模块方法,如os.system、os.spawn*、os.popen*、commands.*等。subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

1、subprocess原理以及常用的封装函数

  • 运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序
  • 在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
  • subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用
  • 另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

subprocess常用函数:

#1、返回执行状态:0 执行成功
retcode = subprocess.call(['ping', 'www.baidu.com', '-c5'])

#2、返回执行状态:0 执行成功,否则抛异常
subprocess.check_call(["ls", "-l"])

#3、执行结果为元组:第1个元素是执行状态,第2个是命令结果
>>> ret = subprocess.getstatusoutput('pwd')
>>> ret
(0, '/test01')

#4、返回结果为 字符串 类型
>>> ret = subprocess.getoutput('ls -a')
>>> ret
'.\n..\ntest.py'


#5、返回结果为'bytes'类型
>>> res=subprocess.check_output(['ls','-l'])
>>> res.decode('utf8')
'总用量 4\n-rwxrwxrwx. 1 root root 334 11月 21 09:02 test.py\n'

将dos格式文件转换成unix格式:

subprocess.check_output(['chmod', '+x', filepath])
subprocess.check_output(['dos2unix', filepath])

2、subprocess.Popen()

  • 实际上,上面的几个函数都是基于Popen()的封装(wrapper),这些封装的目的在于让我们容易使用子进程
  • 当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程
  • 与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待(也就是阻塞block)
  • 从运行结果中看到,父进程在开启子进程之后并没有等待child的完成,而是直接运行print。

child.wait()等待子进程执行:

#1、先打印'parent process'不等待child的完成
import subprocess
child = subprocess.Popen(['ping','-c','4','www.baidu.com'])
print('parent process')

#2、后打印'parent process'等待child的完成
import subprocess
child = subprocess.Popen('ping -c4 www.baidu.com',shell=True)
child.wait()
print('parent process')
    child.poll()                                 # 检查子进程状态
    child.kill()                                  # 终止子进程
    child.send_signal()                   # 向子进程发送信号
    child.terminate()                       # 终止子进程

3、subprocess.PIPE 将多个子进程的输入和输出连接在一起

  • subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走
  • child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
  • 注意:communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成

分步执行cat /etc/passwd | grep root命:

import subprocess
#下面执行命令等价于: cat /etc/passwd | grep root
child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["grep","root"],stdin=child1.stdout, stdout=subprocess.PIPE)
out = child2.communicate()               #返回执行结果是元组
print(out)
#执行结果: (b'root:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin\n', None)

获取ping命令执行结果:

import subprocess

list_tmp = []
def main():
    p = subprocess.Popen(['ping', 'www.baidu.com', '-c5'], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
    while subprocess.Popen.poll(p) == None:
        r = p.stdout.readline().strip().decode('utf-8')
        if r:
            # print(r)
            v = p.stdout.read().strip().decode('utf-8')
            list_tmp.append(v)
main()
print(list_tmp[0])

4. python常用模块之 paramiko

在windows中安装paramiko: pip3 install paramiko
paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。跟常用软件xshell 、xftp功能一样,但是可以连接多台服务器,进行复杂的操作。

1、linux中scp命令的使用

ssh root@10.1.0.51            #ssh远程登录

scp -rp aa.txt  root@10.1.0.50:/tmp/               #将本地aa.txt文件复制到10.1.0.50的/tmp文件夹中

2、Paramiko模块作用

  • 1)如果需要使用SSH从一个平台连接到另外一个平台,进行一系列的操作时,
    • 比如:批量执行命令,批量上传文件等操作,paramiko是最佳工具之一。
  • 2)paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接
  • 3)由于使用的是python这样的能够跨平台运行的语言,所以所有python支持的平台,如Linux, Solaris,
    BSD,MacOS X, Windows等,paramiko都可以支持
  • 4)如果需要使用SSH从一个平台连接到另外一个平台,进行一系列的操作时,paramiko是最佳工具之一
  • 5)现在如果需要从windows服务器上下载Linux服务器文件:
    • a. 使用paramiko可以很好的解决以上问题,它仅需要在本地上安装相应的软件(python以及PyCrypto)
    • b. 对远程服务器没有配置要求,对于连接多台服务器,进行复杂的连接操作特别有帮助。

3、paramiko基于用户名密码连接

远程执行命令:

import paramiko

# 1 创建SSH对象
ssh = paramiko.SSHClient()
# 2 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 3 连接服务器
ssh.connect(hostname='1.1.1.3', port=22, username='root', password='chnsys@2016')

# 4 执行命令                                         #stdin标准输入: 自己输入的命令
stdin, stdout, stderr = ssh.exec_command('pwd')      # stdout标准输出:  命令执行结果
# 5 获取命令结果                                     #stderr标准错误:  命令执行报错的结果
res, err = stdout.read(), stderr.read()
result = res if res else err
print(result.decode())                              #运行结果: /root

# 6 关闭连接
ssh.close()

SFTPClient实现对Linux服务器上传和下载:

import paramiko

#1 连接客户端
transport = paramiko.Transport(('10.1.0.50',22))
transport.connect(username='root',password='chnsys@2016')

#2 定义与客户端交互    将刚刚定义的transport当参数传递给他
sftp = paramiko.SFTPClient.from_transport(transport)
#3 将location.py 上传至服务器 /tmp/test.py
sftp.put(r'C:\bbb\file.txt', '/tmp/file.txt')

#4 将remove_path 下载到本地 local_path
sftp.get('/tmp/file.txt',r'C:\bbb\file.txt')

#5 关闭连接
transport.close()

5. python常用模块之 re

# 正则表达式,就是做字符串匹配的,在re模块出现之前就有这个正则表达式了,任何语言都有这个,
# 要使用Python来操作正则表达式,就要使用到re模块了,
# # 正则表达式只和字符串匹配有关系,和其他的数据类型没有关系,


# 应用非常的广泛,
# 比如手机号,
# 比如身份证号
# 比如邮箱,

1、常用正则表达式符号

⒈通配符( . )

  • 作用:点(.)可以匹配除换行符以外的任意一个字符串
  • 例如:‘.ython’ 可以匹配‘aython’ ‘bython’ 等等,但只能匹配一个字符串

⒉转义字符( \ )

  • 作用:可以将其他有特殊意义的字符串以原本意思表示
  • 例如:‘python.org’ 因为字符串中有一个特殊意义的字符串(.)所以如果想将其按照普通意义就必须使用这样表示: ‘python.org’ 这样就只会匹配‘python.org’ 了
  • 注:如果想对反斜线(\)自身转义可以使用双反斜线(\)这样就表示 ’\’

⒊字符集

  • 作用:使用中括号来括住字符串来创建字符集,字符集可匹配他包括的任意字串
        ①‘[pj]ython’ 只能够匹配‘python’  ‘jython’

        ② ‘[a-z]’ 能够(按字母顺序)匹配a-z任意一个字符

        ③‘[a-zA-Z0-9]’ 能匹配任意一个大小写字母和数字    

        ④‘[^abc]’ 可以匹配任意除a,b和c 之外的字符串

⒋管道符

  • 作用:一次性匹配多个字符串

  • 例如:’python|perl’ 可以匹配字符串‘python’ 和 ‘perl’

⒌可选项和重复子模式(在子模式后面加上问号?)

  • 作用:在子模式后面加上问号,他就变成可选项,出现或者不出现在匹配字符串中都是合法的
  • 例如:r’(aa)?(bb)?ccddee’ 只能匹配下面几种情况
         ‘aabbccddee’

         ‘aaccddee’

         ‘bbccddee’

         ‘ccddee’

⒍字符串的开始和结尾

          ①  ‘w+’ 匹配以w开通的字符串

          ②  ‘^http’ 匹配以’http’ 开头的字符串

          ③‘ $com’ 匹配以‘com’结尾的字符串

7.最常用的匹配方法

          \d     匹配任何十进制数;它相当于类 [0-9]。
          \D     匹配任何非数字字符;它相当于类 [^0-9]。
          \s     匹配任何空白字符;它相当于类 [ fv]。
          \S     匹配任何非空白字符;它相当于类 [^ fv]。
          \w     匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
          \W     匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。

          \w*    匹配所有字母字符

          \w+    至少匹配一个字符

re模块更详细表达式符号:

 1 '.'         默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
 2 '^'         匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
 3 '$'         匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
 4 '*'         匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
 5 '+'         匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
 6 '?'         匹配前一个字符1次或07 '{m}'       匹配前一个字符m次
 8 '{n,m}'     匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
 9 '|'         匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
10 '(...)'     分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
11  
12 '\A'       只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
13 '\Z'       匹配字符结尾,同$
14 '\d'       匹配数字0-9
15 '\D'       匹配非数字
16 '\w'       匹配[A-Za-z0-9]
17 '\W'       匹配非[A-Za-z0-9]
18 's'        匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
19 \b           匹配一个单词边界,也就是指单词和空格间的位置,如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”
20 \B           匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”

2、re模块常用函数

在这里插入图片描述

四.字符编码

  • 各种编码由来
    • ASCII : 不支持中文(一个字母一个字节:a/b/c
    • GBK : 是中国的中文字符,其包含了简体中文和繁体中文的字符
    • Unicode : 万国编码(Unicode 包含GBK)
  • Unicode(每个字母需要用两个字节:a/b/c
    • 存储所有字符串都用连个字节
    • Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码
    • 规定所有的字符和符号最少由 16 位来表示(2个字节),即:2 **16 = 65536
    • 这里还有个问题:使用的字节增加了,那么造成的直接影响就是使用的空间就直接翻倍了
  • Utf-8 : 可变长码, 是Unicode 的扩展集
    • UTF-8编码:是对Unicode编码的压缩和优化,他不再使用最少使用2个字节,而是将所有的字符和符号进行分类
    • ascii码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存…
    • 存一个a字母用一个字节,存一个中文用三个字节
  • python2与python3的几个区别
    • Python2默认 编码方式为ASCII, Python3 默认编码方式为UTF-8(是Unicode 的扩展集)
    • python2中字符串有str和unicode两种类型, python3 中字符串有str和字节(bytes) 两种类型
    • python3中不再支持u中文的语法格式
  • python2和python3中编码转换
    • 在python3中字符串默认是unicode所以不需要decode(),直接encode成想要转换的编码如gb2312
    • 在python2中默认是ASCII编码,必须先转换成Unicode,Unicode 可以作为各种编码的转换的中转站
发布了46 篇原创文章 · 获赞 10 · 访问量 1816

猜你喜欢

转载自blog.csdn.net/longlong6682/article/details/104773626