Python基础(二)

一、内置函数

  如何查看Python内置函数?

  方式一:官方文档查看

  方式二:所有内置函数:dir(__builtin__)

      查看某个内置函数的用法:help(函数名),比如:help(str)

      查看某个函数的位置:random.__file__     

 random.__file__
 'd:\\pytho3.6\\lib\\random.py'

二、collection系列

  1.计数器(Counter) 

"""
Counter
Counter是一个简单的计数器,例如,统计字符出现的个数:
"""
from collections import Counter
c = Counter('programming')
print(c)
a = Counter({'a':12,'b':43})
# Counter具有字典所有的功能+自己的功能
a = Counter({'name':'zhangyafei','age':23})
a['name']
Out[108]: 'zhangyafei'

  2、有序字典(orderedDict )

  orderdDict是对字典类型的补充,他记住了字典元素添加的顺序

"""
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict:
"""
from collections import OrderedDict
d = dict([('a', 1), ('b', 2), ('c', 3)])
d # dict的Key是无序的
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
od # OrderedDict的Key是有序的
# 注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

  3、默认字典(defaultdict)

"""
defaultdict
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
"""
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
dd['key1'] # key1存在
dd['key2'] # key2不存在,返回默认值

  4、可命名元组(namedtuple) 

  根据nametuple可以创建一个包含tuple所有功能以及其他功能的类型。 

"""
namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。
这样一来,我们用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。
"""
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
p.x
p.y
Circle = namedtuple('Circle', ['x', 'y', 'r'])

  5、双向队列(deque)

  一个线程安全的双向队列 

"""
deque
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
"""
from collections import deque
q = deque(['a', 'b', 'c'])
q.append('x')
q.appendleft('y')
q

三、可变类型和不可变类型

  可变类型:列表、字典、集合

  不可变类型:数字、布尔、字符串、元组

  这里的可变不可变,是指内存中的那块内容(value)是否可以被改变

  •  不可变类型
# 数字
In [93]: id(a)
Out[93]: 1850764656

In [94]: a += 1

In [95]: id(a)
Out[95]: 1850764688

# 字符串
In [88]: a = '123'

In [89]: id(a)
Out[89]: 942746951216

In [90]: a += '456'

In [91]: id(a)
Out[91]: 942746981576

# 元组
In [79]: a = (1,2,3)

In [80]: b = (4,5,6)

In [81]: id(a)
Out[81]: 942746089296

In [82]: id(b)
Out[82]: 942746396784

In [83]: a[1]
Out[83]: 2

In [84]: a[1] = 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-84-23f2cf2bdf70> in <module>()
----> 1 a[1] = 3

TypeError: 'tuple' object does not support item assignment

 可变类型

# 列表
In [29]: a = [1,2,3]

In [30]: id(a)
Out[30]: 942745728456

In [31]: a.append(4)

In [32]: id(a)
Out[32]: 942745728456

# 字典
In [33]: c = {'k1':'v1','k2':'v2'}

In [34]: id(c)
Out[34]: 942746626232

In [35]: c['k3'] = 'v3'

In [36]: c
Out[36]: {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

In [37]: id(c)
Out[37]: 942746626232

字典的key只能是不可变类型,可变类型不可哈希

In [96]: dic = {1:'v1',2:'v2'}

In [97]: dic = {'k1':'v1','k2':'v2'}

In [98]: dic = {(1,2):'v1',(2,3):'v2'}

In [99]: dic = {[1,2]:'v1',[2,3]:'v2'}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-99-4e27abb80f56> in <module>()
----> 1 dic = {[1,2]:'v1',[2,3]:'v2'}

TypeError: unhashable type: 'list'

In [100]: dic = {{'k':'v'}:'v1',{'k1':'v1'}:'v2'}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-100-25f010250cc4> in <module>()
----> 1 dic = {{'k':'v'}:'v1',{'k1':'v1'}:'v2'}

TypeError: unhashable type: 'dict'

四、迭代器、生成器、可迭代对象

    关于此部分内容大家请看我这篇文章

  Python生成器、迭代器,可迭代对象

五、深浅拷贝

  何为深浅拷贝? 

In [49]: a = [1,2,3]
In [50]: b = a
In [51]: a.append(4)
In [52]: a
Out[52]: [1, 2, 3, 4]
In [53]: b
Out[53]: [1, 2, 3, 4]

  唉?我们把a赋值给了b,结果a添加了一个元素,b也跟着添加了。这是为什么,我复制了一份不就和原来的没关系了吗?

  这其实就是浅拷贝,b = a其实是把a指向的那个列表的内存的引用给了b,当a指向的那个内存发生改变时,b也会同时发生变化。这就是浅拷贝。

  那我们不想拷贝它的引用,我们只想拷贝值怎么办?a.copy()就搞定了

In [54]: a = [1,2,3]
In [55]: b = a.copy()  # 深拷贝,只拷贝当前变量所在内存中存储的值,而不是引用
In [56]: b
Out[56]: [1, 2, 3]
In [57]: a.append(4)
In [58]: a
Out[58]: [1, 2, 3, 4]
In [59]: b
Out[59]: [1, 2, 3]

六、文件IO操作

     1. 打开和关闭文件

  • 打开文件:open 函数
   "你必须先用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。"
语法:
file object = open(file_name [, access_mode][, buffering])
各个参数的细节如下:
file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。
access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
buffering:如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。
不同模式打开文件的完全列表:
模式  描述
r  以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+    以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
w  打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+    以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
a  打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+    以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

以下是和file对象相关的所有属性的列表:
属性 描述
file.closed    返回true如果文件已被关闭,否则返回false。
file.mode  返回被打开文件的访问模式。
file.name  返回文件的名称。
"""   

示例

open(文件名,访问模式)
    f = open("test.txt","w")
  • 关闭文件: close()方法
File 对象的 close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。
当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。
语法:
fileObject.close()

 2.  读写文件

4.1 write()方法
    write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
    write()方法不会在字符串的结尾添加换行符('\n'):
    语法:
    fileObject.write(string)
    在这里,被传递的参数是要写入到已打开文件的内容。
    例子:
    f = open(file,'w',encoding='utf-8')
    f.write('ip_type,ip,port,speed,position,live_time,update_time\n') 
    # 关闭打开的文件
    fo.close()
4.2 read()方法:
        "从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。"
        语法:
        fileObject.read([count])
        在这里,被传递的参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾。
        # 打开一个文件
        fo = open("foo.txt", "r+")
        str = fo.read(10)
        print("读取的字符串是 : ", str)
        # 关闭打开的文件
        fo.close()
        以上实例输出结果:
读取的字符串是 :  www.runoob
4.3 readline()方法:一次读取一行
4.4 readlines()方法:读取所有内容,以列表形式返回,每一行作为列表中的一个元素。
4.5 文件位置:
    文件定位
    tell()方法告诉你文件内的当前位置, 换句话说,下一次的读写会发生在文件开头这么多字节之后。
    seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
    如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。

Python的os模块给我们提供执行文件处理操作的方法
3.  删除文件

remove()方法
你可以用remove()方法删除文件,需要提供要删除的文件名作为参数。
语法:
os.remove(file_name)
例子:
下例将删除一个已经存在的文件test2.txt。
import os
# 删除一个已经存在的文件test2.txt
os.remove("test2.txt")

   4. 文件重命名

 

rename()方法需要两个参数,当前的文件名和新文件名。
语法:
os.rename(current_file_name, new_file_name)
例子:
下例将重命名一个已经存在的文件test1.txt。
import os
# 重命名文件test1.txt到test2.txt。
os.rename( "test1.txt", "test2.txt" )

 

 5. 创建和删除文件夹

  创建文件夹

mkdir()方法
可以使用os模块的mkdir()方法在当前目录下创建新的目录们。你需要提供一个包含了要创建的目录名称的参数。
语法:
os.mkdir("newdir")
例子:
下例将在当前目录下创建一个新目录test。
import os
# 创建目录test
os.mkdir("test")

  删除文件夹

r、mdir()方法
rmdir()方法删除目录,目录名称以参数传递。
在删除这个目录之前,它的所有内容应该先被清除。
语法:
os.rmdir('dirname')
例子:
以下是删除" /tmp/test"目录的例子。目录的完全合规的名称必须被给出,否则会在当前目录下搜索该目录。
import os
# 删除”/tmp/test”目录
os.rmdir( "/tmp/test"  )

  6. 获取和切换目录

获取当前目录
getcwd()方法:
getcwd()方法显示当前的工作目录。
语法:
os.getcwd()

切换指定目录
chdir()方法
可以用chdir()方法来改变当前的目录。chdir()方法需要的一个参数是你想设成当前目录的目录名称。
语法:
os.chdir("newdir")

 7. 获取当前目录下的所有文件列表

获取当前目录下所有文件列表
os.listdir()
os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])

示例

#1.获取文件名
old_file_name = input("请输入要备份的文件名(需要后缀):")

#2。打开这个文件("r")
f_read = open(old_file_name,"r")

#new_file_name = old_file_name+"[复件]"
position = old_file_name.rfind(".")
new_file_name = old_file_name[0:position]+"[复件]"+old_file_name[position:]

#3.创建一个文件,xxx[复件].txt
f_write = open(new_file_name,"w")


#4.往源文件中读取内容,写入备份的文件中
#content = f_read.read()
#f_write.write(content)
while True:
    content = f_read.read(1024)

    if len(content)==0:
        break
    f_write.write(content)

#5.关闭两个文件
f_read.close()
f_write.close()

文件备份
文件备份
import os

#1. 获取一个要重命名的文件夹的名字

folder_name = input("请输入要重命名的文件夹:")

#2.获取文件夹中所有的文件名字

file_names = os.listdir(folder_name)
'''
第一种方法
os.chdir(folder_name)

3.对获取的名字进行重命名即可

for name in file_names:
    print(name)
    os.rename(name,"[京东出品]-"+name)
'''
#第二种方法
for name in file_names:
    #print(name)
    old_file_name = "./"+folder_name+"/"+name
    new_file_name = "./"+folder_name+"/"+"[京东出品]"+name
    os.rename(old_file_name,new_file_name)
    print(new_file_name)

批量文件重命名
批量文件重命名

自定义函数

一、为什么要有函数

while True:
    if cpu利用率 > 90%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

    if 硬盘使用空间 > 90%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

    if 内存占用 > 80%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

我们发现,if下面的相同的内容被被多次调用,代码很冗余,于是,我们可以这样写

def 发送邮件(内容)
    #发送邮件提醒
    连接邮箱服务器
    发送邮件
    关闭连接

while True:

    if cpu利用率 > 90%:
        发送邮件('CPU报警')

    if 硬盘使用空间 > 90%:
        发送邮件('硬盘报警')

    if 内存占用 > 80%:

上述的两种实现方式,第二次必然比第一次的重用性和可读性要好,其实这就是函数式编程和面向过程编程的区别:

  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

函数式编程最重要的是增强代码的重用性和可读性

二、函数的定义和调用

函数定义  def 函数名(参数):
            函数体
       return 返回值
函数调用   函数名()

函数的定义主要有如下要点:

def:表示函数的关键字
  函数名:函数的名称,日后根据函数名调用函数
  函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
  参数:为函数体提供数据
  返回值:当函数执行完毕后,可以给调用者返回数据。

  以上要点中,比较重要有参数和返回值:

  1.返回值:函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。     

def 发送短信():
    发送短信的代码...
 
    if 发送成功:
        return True
    else:
        return False
  
while True:  
    # 每次执行发送短信函数,都会将返回值自动赋值给result
    # 之后,可以根据result来写日志,或重发等操作
 
    result = 发送短信()
    if result == False:
        记录日志,短信发送失败...

2. 参数

  ·为什么要有参数?

def CPU报警邮件()
    #发送邮件提醒
    连接邮箱服务器
    发送邮件
    关闭连接

def 硬盘报警邮件()
    #发送邮件提醒
    连接邮箱服务器
    发送邮件
    关闭连接

def 内存报警邮件()
    #发送邮件提醒
    连接邮箱服务器
    发送邮件
    关闭连接
 
while True:
 
    if cpu利用率 > 90%:
        CPU报警邮件()
 
    if 硬盘使用空间 > 90%:
        硬盘报警邮件()
 
    if 内存占用 > 80%:
        内存报警邮件()

上例,无参数实现
上例,无参数实现
def 发送邮件(邮件内容)

    #发送邮件提醒
    连接邮箱服务器
    发送邮件
    关闭连接

 
while True:
 
    if cpu利用率 > 90%:
        发送邮件("CPU报警了。")
 
    if 硬盘使用空间 > 90%:
        发送邮件("硬盘报警了。")
 
    if 内存占用 > 80%:
        发送邮件("内存报警了。")

上列,有参数实现
上例,有参数实现

函数的有三中不同的参数:

  • 普通参数
  • 默认参数
  • 动态参数
def sum_2_nums(a,b):
    #a = 10
    #b = 20
    result = a+b
    print("%d + %d = %d"%(a,b,result))

num1 = int(input("请输入第一个数字:"))
num2 = int(input("请输入第二个数字:"))

#调用函数
sum_2_nums(num1,num2)
普通参数
def test(a,d,b=22,c=33):
    result = a+b+c
    print(a)
    print(b)
    print(c)
    print(d)
    print("result=%d"%result)
    
test(11,22,b=12)
test(33,33)
test(d=44,a=11,c=44)
缺省参数
def sum_2_nums(a,b,c=33,*args,**kwargs):
    print("-"*30)
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)
    #result = a+b+args
    #print("result=%d"%result)

sum_2_nums(11,22,33,44,55,66,77,task=99,done=89)
#sum_2_nums(11)#错误,因为形参中至少要2个实参
不定长参数
def test(a,b,c=33,*args,**kwargs):
    print("-"*30)
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)
    #result = a+b+args
    #print("result=%d"%result)

#test(11,22,33,44,55,66,77,task=99,done=89)
A=(44,55,66)
B={"name":"laowang","age":18}
test(11,22,33,*A,**B)
#sum_2_nums(11)#错误,因为形参中至少要2个实参
拆包、元组和字典
def test_kwargs(actions=None, **kwargs):
    print('actions:', actions)
    print('kwargs:', kwargs)


def test_args(actions=None, *args):
    print('actions:', actions)
    print('args:', args)


test_args([1,2,3])
# actions: [1, 2, 3]
# args: ()

test_args(1,2,3)
# actions: 1
# args: (2, 3)

test_args(*[1, 2, 3])
# actions: 1
# args: (2, 3)

test_kwargs({'get':'list', 'post': 'create'})
# actions: {'get': 'list', 'post': 'create'}
# kwargs: {}

test_kwargs(get='list', post='create')
# actions: None
# kwargs: {'get': 'list', 'post': 'create'}

test_kwargs(**{'get':'list', 'post': 'create'})
# actions: None
# kwargs: {'get': 'list', 'post': 'create'}
args和kwargs

实例:打印佛祖

def print_fuzu():
    print("                           _ooOoo_  ")
    print("                          o8888888o  ")
    print("                          88  .  88  ")
    print("                          (| -_- |)  ")
    print("                           O\\ = /O  ")
    print("                       ____/`---'\\____  ")
    print("                     .   ' \\| |// `.  ")
    print("                      / \\||| : |||// \\  ")
    print("                    / _||||| -:- |||||- \\  ")
    print("                      | | \\\\\\ - /// | |  ")
    print("                    | \\_| ''\\---/'' | |  ")
    print("                     \\ .-\\__ `-` ___/-. /  ")
    print("                  ___`. .' /--.--\\ `. . __  ")
    print("               ."" '< `.___\\_<|>_/___.' >'"".  ")
    print("              | | : `- \\`.;`\\ _ /`;.`/ - ` : | |  ")
    print("                \\ \\ `-. \\_ __\\ /__ _/ .-` / /  ")
    print("        ======`-.____`-.___\\_____/___.-`____.-'======  ")
    print("                           `=---='  ")
    print("  ")
    print("        .............................................  ")
    print("                 佛祖镇楼                  BUG辟易  ")
    print("         佛曰:  ")
    print("                 写字楼里写字间,写字间里程序员;  ")
    print("                 程序人员写程序,又拿程序换酒钱。  ")
    print("                 酒醒只在网上坐,酒醉还来网下眠;  ")
    print("                 酒醉酒醒日复日,网上网下年复年。  ")
    print("                 但愿老死电脑间,不愿鞠躬老板前;  ")
    print("                 奔驰宝马贵者趣,公交自行程序员。  ")
    print("                 别人笑我忒疯癫,我笑自己命太贱;  ")
    print("                 不见满街漂亮妹,哪个归得程序员?")

print_fuzu()
打印佛祖

扩展:发送邮件实例

import smtplib
        from email.mime.text import MIMEText
        from email.utils import formataddr


        msg = MIMEText('邮件内容', 'plain', 'utf-8')
        msg['From'] = formataddr(["张亚飞",'1271570224@qq.com'])
        msg['To'] = formataddr(["走人",'2464392538@qq.com'])
        msg['Subject'] = "主题"

        server = smtplib.SMTP_SSL("smtp.qq.com", 465)
        server.login("1271570224@qq.com", "euvtrglugggubagj")
        server.sendmail('1271570224@qq.com', ['2464392538@qq.com',], msg.as_string())
        server.quit()

三、lambda表达式

  匿名函数:lambda 参数:式子

  作用:书写比较简单,不需要声明函数的名称,当功能为一些比较简单的加加减减时,用lambda匿名函数,否则用def

  注:匿名函数默认带有返回值

  实例:对字母排序

s = 'string'
s = "".join((lambda x: (x.sort(), x)[1])(list(s)))
s
Out[4]: 'ginrst'

  应用:列表元素为字典时按照字典的value值排序,list.sort(key x:x['age'])

实例:
def test(a,b,func):
    result = func(a,b)
    print(result)

test(11,22,lambda x,y:x+y)
匿名函数

lambda存在意义就是对简单函数的简洁表示

Python高级特性

一、 map

  求一个序列或者多个序列进行函数映射(遍历)之后的值,就该想到map这个函数,它是python自带的函数,在python3.*之后返回的是迭代器,同filter,需要进行列表转换.

 

 

调用: map(function,iterable1,iterable2),function中的参数值不一定是一个x,也可以是x和y,甚至多个;后面的iterable表示需要参与function运算中的参数值,有几个参数值
就传入几个iterable map函数的原型是map(function, iterable, …),它的返回结果是一个列表。
  参数function传的是一个函数名,可以是python内置的,也可以是自定义的。   参数iterable传的是一个可以迭代的对象,例如列表,元组,字符串这样的。 这个函数的意思就是将function应用于iterable的每一个元素,结果以列表的形式返回。注意到没有,iterable后面还有省略号,意思就是可以传很多个iterable,如果有额外的 iterable参数,并行的从这些参数中取元素,并调用function。如果一个iterable参数比另外的iterable参数要短,将以None扩展该参数元素。 map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
# 1.map自定义函数
def f(x):
    return x*x
a = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(a)
# 2.map复杂函数
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
== [str(x) for x in [1,2,3,4,5,6,7,8,9]]
# 3.实例
def add(x,y,z):
    return x,y,z

list1 = [1,2,3]
list2 = [1,2,3,4]
list3 = [1,2,3,4,5]
list4 = [1,2,3,4,5,6]
res = map(add, list1, list2, list3)
list(res)

def add(x,y,z):
    return x+y+z
list1=[1,2,3]
list2=[1,2,3]
list3=[1,2,3]
list(map(add,list1,list2,list3))

func = lambda x,y,z:x+y+z
func(list1,list2,list3)

def format_name(s):
return s.capitalize()
list(map(lambda x:x.capitalize(), ['adam', 'LISA', 'barT']))

foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]

list(map(lambda x: x * 2 + 10, foo))
print ([x * 2 + 10 for x in foo]) 
map实例

二、filter

  filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数。

调用: filter(function,sequence),function可以是匿名函数或者自定义函数,它会对后面的sequence序列的每个元素判定是否符合函数条件,返回TRUE或者FALSE,从而只留下TRUE
    的元素;sequence可以是列表、元组或者字符串 Python内建的filter()函数用于过滤序列。和map()类似,filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True
还是False决定保留还是丢弃该元素。
例1,在一个list中,删掉偶数,只保留奇数,可以这么写:
def is_old(x):
    return x%2 == 0
list(filter(is_old,[1,2,3,4,5,6,7,8,9,10]))
print([x for x in foo if x%3==0])

例2:在一个list中,只保留能被三整除的数字
list(filter(lambda x: x % 3 == 0, foo)))
print ([x for x in foo if x % 3 == 0])
filter实例

三、reduce 

对一个序列进行压缩运算,得到一个值。但是reduce在python2的时候是内置函数,到了python3移到了functools模块,所以使用之前需要 from functools import reduce 

 

 

调用: reduce(function,iterable),其中function必须传入两个参数,iterable可以是列表或者元组 
reduce() 函数会对参数序列中元素进行累积。
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数
function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数
据用 function 函数运算,最后得到一个结果。
reduce(function, iterable[, initializer])
function -- 函数,有两个参数
iterable -- 可迭代对象
initializer -- 可选,初始参数
from functools import reduce 
print (reduce(lambda x, y: x + y, foo))

def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

def str2int(s):
    return reduce(lambda x,y: x*10+y, map(char2num, s))
print(str2int('12345'))

def kfactorial(k):
    """求k的阶乘"""
    if k == 0 or k == 1:
        return 1
    from functools import reduce
    return reduce(lambda x,y:x*y,list(range(1,k+1)))

def kfactorial2(k):
    a = 1
    for i in range(1,k+1):
        a *= i
    return a

def kfactorial3(k):
    if k == 0 or k == 1:
        return 1
    else:
        return kfactorial3(k-1)
    
    
kfactorial(5)
kfactorial2(6)
kfactorial3(7)
reduce实例

四、闭包

  定义:在函数内部再定义⼀个函数, 并且这个函数⽤到了外边函数的变量, 那么将这个函数成为闭包 

  • 示例
def test(number):
	print("-----1------")
	#在函数内部再定义⼀个函数, 并且这个函数⽤到了外边函数的变量, 那么将这个函数成为闭包
	def test_in(number2):
		print("-----2-----")
		print(number+number2)

	print("---3---")
	#其实这⾥返回的就是闭包的结果
	return test_in
#给test函数赋值, 这个100就是给参数number
ret = test(100)
print("-"*30)
#注意这⾥的1其实给参数number2
ret(1)
ret(100)
ret(200)
def test(a,b):
    def test_in(x):
        print(a*x+b)

    return test_in

line1 =test(1,1)
line1(0)
line2 = test(10,4)
line2(0)

line1(0)
闭包案例
"""闭包中修改外部函数变量应声明nonlocal"""


def test():
    x = 10

    def test_in():
        nonlocal x
        x += 1
        print(x)
    return test_in


c = test()
c()
# 不声明nonlocal   UnboundLocalError: local variable 'x' referenced before assignment
# 声明之后 11
闭包中修改外部函数变量应声明nonlocal

五、装饰器

  装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作。换句话说,Decorator 通过返回包装对象实现间接调用,以此插入额外逻辑。应该算是言简意赅了

def w1(func):
    def inner():
        print("---正在验证权限---")
        if True:
            func()
        else:
            print("没有权限")
    return inner
@w1
def f1():
    print("---f1---")
@w1
def f2():
    print("---f2---")

#innerFunc = w1(f1)
#innerFunc()
#f1 = w1(f1)
f1()
f2()
普通装饰器
#定义函数: 完成包裹数据
def makeBold(fn):
    def wrapped():
        print("-----1-----")
        return "<b>" + fn() + "</b>"
    return wrapped

#定义函数: 完成包裹数据
def makeItalic(fn):
    def wrapped():
        print("-------2-----")
        return "<i>" + fn() + "</i>"
    return wrapped

@makeBold
@makeItalic
def test3():
    print("-------3------")
    return "hello world-3"


print(test3())
多个装饰器
def w1(func):
    print("----正在装饰1----")
    def wrpped():
        print("----正在验证权限1------")
        return func()
    return wrpped

def w2(func):
    print("----正在装饰2----")
    def wrpped():
        print("----正在验证权限2------")
        return func()
    return wrpped

#只要python解释器执行到了这个代码,那么就会自动的进行装饰,而不是等到调用的时候才装饰的
@w1 #f1 = w1(w2(f1()))
@w2 #f1 = w2(f1())
def f1():
    print("-----f1-----")



#在调用f1之前,已经进行装饰了
f1()
什么时候执行
def func(functionName):
    print("-----func---1----")
    def func_in():
        print("----func_in---1--")
        functionName()
        print("---func_in---2---")

    print("----func---2---")
    return func_in

@func
def test():
    print("---test---")

#test = func(test)

test()
装饰器对无参数的函数装饰
def func(functionName):
    print("-----func---1----")
    def func_in(a,b):
        print("----func_in---1--")
        functionName(a,b)
        print("---func_in---2---")

    print("----func---2---")
    return func_in
@func
def test(a,b):
    print("---test- a=%d,b=%d---"%(a,b))

#test = func(test)

test(11,22)
有参数
def func(functionName):
    print("-----func---1----")
    def func_in(*args,**kwargs):
        print("----func_in---1--")
        functionName(*args,**kwargs)
        print("---func_in---2---")

    print("----func---2---")
    return func_in

@func
def test(a,b,c):
    print("---test- a=%d,b=%d,c=%d---"%(a,b,c))
@func
def test1(a,b,c,d):
    print("---test- a=%d,b=%d,c=%d,d=%d---"%(a,b,c,d))

#test = func(test)
不定长参数
def func(functionName):
    print("-----func---1----")
    def func_in():
        print("----func_in---1--")
        return functionName()
        print("---func_in---2---")

    print("----func---2---")
    return func_in
@func
def test():
    print("---test----")
    return "haha"

ret = test()
print("test return value is %s"%ret)
有返回值
def func(functionName):
    def func_in(*args,**kwargs):
        print("---记录日志------")
        ret = functionName(*args,**kwargs)
        return ret
    return func_in
@func
def test():
    print("---test----")
    return "haha"

@func
def test2():
    print("----test2---")

@func
def test3(a):
    print("----test3--a=%d--"%a)

ret = test()
print("test return value is %s"%ret)

a = test2()
print("test2 return value is %s"%a)

test3(11)
通用装饰器
def func_arg(arg):
    def func(functionName):
        def func_in():
            print("---记录日志--arg=%s----"%arg)
            if arg=="heihei":
                functionName()
                functionName()
            else:
                functionName()
        return func_in
    return func

#1.先执行func_arg("heihei")函数,这个函数return 的结果是func这个函数的引用
#2.@func
#3使用@func对test进行装饰
@func_arg("heihei")
def test():
    print("---test----")

@func_arg("haha")
def test2():
    print("-----test2------")

test()
test2()
带有参数的装饰器
class Eat(object):
    # 装饰器 Eta
    # :return
    def __init__(self,func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print('i am eating')
        return self.func(*args,**kwargs)


@Eat
def wash():
    # 洗手
    # :return:
    print('i am washing')


wash()
print(wash.__class__)

#
# class Eat(object):
#     """
#     装饰器 Eta
#     :return
#     """
#     def __call__(self, func):
#         @wraps(func)
#         def eat(*args,**kwargs):
#             print('i am eating')
#             return func(*args,**kwargs)
#         return eat
#
#
# @Eat()
# def wash():
#     """
#     洗手
#     :return:
#     """
#     print('i am washing')
#
#
# wash()
# print(wash.__name__)
类装饰器
from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not can_run:
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated
 
@decorator_name
def func():
    return("Function is running")
 
can_run = True
print(func())
# Output: Function is running
 
can_run = False
print(func())
# Output: Function will not run
保留原对象指定属性信息
from functools import wraps


def auth(func):
    @wraps(func)   # 伪装的更彻底
    def inner(*args,**kwargs):
        print('')
        ret = func(*args,**kwargs)
        print('')
        return ret
    return inner


@auth
def index():
    print('index')


@auth
def detail():
    print('index')


print(index.__name__)
print(detail.__name__)
装饰器通用写法
def timeit(func):
    """
    装饰器: 判断函数执行时间
    :param func:
    :return:
    """

    @wraps(func)
    def inner(*args, **kwargs):
        start = time.time()
        ret = func(*args, **kwargs)
        end = time.time() - start
        if end < 60:
            print(f'花费时间:\t{round(end, 2)}秒')
        else:
            min, sec = divmod(end, 60)
            print(f'花费时间\t{round(min)}分\t{round(sec, 2)}秒')
        return ret

    return inner
自定义timeit装饰器

六、递归

利用函数编写如下数列:

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368

# 子问题的重复计算
def fabnacci_rec(n):
    if n == 1 or n == 2:
        return 1
    return fabnacci_rec(n - 1) + fabnacci_rec(n - 2)


def fibonacci_no_rec1(max):
    n, a, b = 1, 0, 1
    while n < max:
        # print(b)
        a, b = b, a + b
        n = n + 1
    return b


# 动态规划 DP 的思想 = 最优子结构递推式 重复子问题
def fibonacci_no_rec2(n):
    f = [0, 1, 1]
    if n > 2:
        for i in range(n - 2):
            num = f[-1] + f[-2]
            f.append(num)
    return f[n]


if __name__ == '__main__':
    print(fabnacci_rec(10))
    print(fibonacci_no_rec1(10))
    print(fibonacci_no_rec2(10))

七、可变、不可变类型 

  可变类型:字典,列表

  不可变类型:数字,字符串,元组,集合

  注:字典中的key值可以位数字,字母,元组,但不可为列表,不符合哈希函数规则

案例

#用来存储名片(列表)
card_infors = []

def print_menu():
    """完成打印功能菜单"""
    print("="*50)
    print(" 名片管理系统 v0.1")
    print(" 1.添加一个名片")
    print(" 2.删除一个名片")
    print(" 3.修改一个名片")
    print(" 4.查询一个名片")
    print(" 5.显示所有名片")
    print(" 6.保存信息")
    print(" 7.退出系统")
    print("="*50)

def add_new_card_infor():
    """完成添加一个新的名片"""
    new_name = input("请输入新的名字:")
    new_qq = input("请输入新的qq:")
    new_weixin = input("请输入新的微信:")
    new_addr = input("请输入新的住址:")

    #定义一个新的字典,用来存储一个新的名片
    new_infor ={}
    new_infor['name'] = new_name
    new_infor['qq'] = new_qq
    new_infor['weixin'] = new_weixin
    new_infor['addr'] = new_addr

    #将一个字典添加到列表中
    global card_infors
    card_infors.append(new_infor)

    print(card_infors)
def del_card_infor():
    """用来查询一个名片"""
    global card_infors
    find_flag=0
    del_name = input("删除的姓名是:")
    for temp in card_infors:
        if del_name == temp['name']:
            card_infors.remove(temp)
            find_flag = 1
            print(card_infors)
            break
    #判断是否找到了
    if find_flag==0:
        print("查无此人")

def show_all_infor():
    """显示所有的名片信息"""
    global card_infors
    print("姓名\tQQ\t微信\t住址")
    for temp in card_infors:
            print("%s\t%s\t%s\t%s\t"%(temp['name'],temp['qq'],temp['weixin'],temp['addr']))
def chang_card_infor():
    """完成对名片信息的修改"""
    global card_infors

    find_flag=0
    name = input("你要修改的名片的姓名是:")
    for temp in card_infors:
        if name==temp['name']:
            temp['name'] = input("姓名:")
            temp['qq'] = input("qq:")
            temp['weixin'] = input("微信:")
            temp['addr'] = input("地址:")
            print("姓名\tQQ\t微信\t住址")
            print("%s\t%s\t%s\t%s\t"%(temp['name'],temp['qq'],temp['weixin'],temp['addr']))
            find_flag=1
            break
    if find_flag==0:
        print("查无此人")
def find_card_infor():
    """查找名片上的信息"""
    global card_infors
    find_name = input("请输入要查找的名字:")
    find_flag = 0 #默认表示没有找到
    for temp in card_infors:
        if find_name == temp['name']:
            print("%s\t%s\t%s\t%s\t"%(temp['name'],temp['qq'],temp['weixin'],temp['addr']))
            find_flag = 1
            break   
    #else:
        #print("查无此人")
              #p判断是否找到了
    if find_flag==0:
        print("查无此人")


def save_2_file():
    """把已经添加的信息保存到文件中"""
    #f = open("backup.data","w")
    f = open("backup.data", "w")
    #f.write(str(card_infors)
    f.write(str(card_infors))
    f.close()

def load_infor():
    global card_infors
    try:
        f = open("backup.data","r")
        card_infors = eval(f.read())
        f.close()
    except Exception:
        pass

def main():    
    """完成对整个程序的控制"""

    #恢复(加载)之前的数据到程序中
    load_infor()
    #1. 打印功能提示
    print_menu()
    while True:        
        #2.获取用户的输入
        num = int(input("请输入操作序列:"))
        #3.根据用户的输入执行相应的功能
        if num==1:
            add_new_card_infor()

        elif num==2:
            del_card_infor()

        elif num==3:
            chang_card_infor()

        elif num==4:
            find_card_infor()

        elif num==5:
            show_all_infor()

        elif num==6:
            save_2_file()

        elif num==7:
            break
        else:
            print("你输入的信息有误,请重新输入!")

if __name__=="__main__":
    main()
名片管理系统文件版

 

posted @ 2018-12-12 23:41  DreamBoy_张亚飞  阅读(332)  评论(0编辑  收藏  举报