list1 = set([1, 2, 3, 4, 5, 6, 5, 5, 5])
list2 = set([11, 2, 36, 'a', 5, 6, 5, 5, 5])
list3 = set([1, 2, 3])
list4 = set(['a', 'b', 'c']) 求交集
print(list1.intersection(list2))
print(list1&list2)
输出{2, 5, 6} 求并集
print(list1.union(list2))
print(list1 | list2)
输出{1, 2, 3, 4, 5, 6, 36, 'a', 11} 求差集
print(list1.difference(list2)) #在list1不在list2
print(list1 - list2)
输出{1, 3, 4}
print(list2.difference(list1)) #在list2不在list1
print(list2 - list1)
输出{'a', 11, 36} 子集(无运算符)
print(list1.issubset(list2))
输出False
print(list3.issubset(list1))
输出True 对称差集:两个集合互相没有的取出来放一起
print(list1.symmetric_difference(list2))
输出{1, 3, 36, 4, 11, 'a'} isdisjoint:Return True if two sets have a null intersection #两个集合没有交集返回true,否则返回false
print(list3.isdisjoint(list1))
输出False
print(list1.isdisjoint(list4))
输出True
list1 = set([1, 2, 3, 4, 5, 6, 5, 5, 5])
list2 = set([11, 2, 36, 'a', 5, 6, 5, 5, 5])
list3 = set([1, 2, 3])
list4 = set(['a', 'b', 'c'])
集合的创建方式
1)
l = [1,3,4,5]
s = set(l) 2)
s = {1,2,3,4} #用{}直接创建集合
集合与列表、字符串、元组的转换:
>>> l = (1,2,3,4,1,2,3) #元组转换为集合去重
>>> s = set(l)
>>> s
{1, 2, 3, 4} >>> l = '' #字符串转换为集合去重
>>> s = set(l)
>>> s
{'', '', ''} >>> l = [1,2,3,1,1,1,2,3,3] #列表转换为集合去重
>>> s = set(l)
>>> s
{1, 2, 3}
集合元素增删改查:
增(与列表对比:集合中没有insert,只有add)
list1.add('new')
print(list1)
list1.update(['new2','new3'])
print(list1)
输出:
{1, 2, 3, 4, 5, 6, 'new'}
{1, 2, 3, 4, 5, 6, 'new3', 'new2', 'new'} difference_update方法:
se = {11, 22, 33, 55}
be = {22, 11, 55} se.difference_update(be) #找出se中存在,be中不存在的集合放到se中
print(se)
结果:{33}
删
pop随机删除集合中的元素并返回删除的元素
remove指定的元素删除,元素不存在,删除会报错
discard不会报错 print(len(list3))
输出:3 print(list1.pop())
输出:1 list4.remove('b')
print(list4)
输出:{'a', 'c'} 集合测试
for i in range(3, 6):
if i in list3:
print('%i is in list1' % i)
else:
print('%i is not in list1' % i)
输出:
3 is in list1
4 is not in list1
5 is not in list1 小结:
x in s 【集合,字典,列表,字符串,全部用这种方法判断一个字符在不在字符串里】
测试 x 是否是 s 的成员 x not in s
测试 x 是否不是 s 的成员 集合练习:
#要求 把new_dict更新到old_dict:
old_dict = {
"#1": 11,
"#2": 22,
"#3": 100,
} new_dict = {
"#1": 33,
"#4": 22,
"#7": 100,
}
for key in old_dict:
if key in new_dict:
old_dict[key] = new_dict[key] for key, value in new_dict.items():
if key not in old_dict:
old_dict[key] = value old_keys = old_dict.keys()
new_keys = new_dict.keys() old_set = set(old_keys)
new_set = set(new_keys) del_set = old_set.difference(new_set)
for key in del_set:
old_dict.pop(key) print(old_dict) #输出:{'#1': 33, '#7': 100, '#4': 22}
重要知识:字符串,列表,字典
Python成员运算符
Python还支持成员运算符,包含的成员,包括字符串,列表或元组
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
#!/usr/bin/python
# -*- coding: UTF-8 -*- a = 10
b = 20
list = [1, 2, 3, 4, 5 ]; if ( a in list ):
print "1 - 变量 a 在给定的列表中 list 中"
else:
print "1 - 变量 a 不在给定的列表中 list 中" if ( b not in list ):
print "2 - 变量 b 不在给定的列表中 list 中"
else:
print "2 - 变量 b 在给定的列表中 list 中" # 修改变量 a 的值
a = 2
if ( a in list ):
print "3 - 变量 a 在给定的列表中 list 中"
else:
print "3 - 变量 a 不在给定的列表中 list 中"
以上实例输出结果:
1 - 变量 a 不在给定的列表中 list 中
2 - 变量 b 不在给定的列表中 list 中
3 - 变量 a 在给定的列表中 list 中
文件操作:
python2 open没有encoding参数
import os
import chardet
import codecs for dirpath,dirnames,filenames in os.walk('/data/usr/src/app/dbmanager/slowlogs'):
for filename in filenames:
file_abs = dirpath+'/'+filename
print(file_abs)
file_handler = open(file_abs, 'rb')
buf = file_handler.read()
result = chardet.detect(buf)
file_handler.close()
print(result) # try:
# file_handler = open(file_abs, encoding='utf-8')
# lines = file_handler.readlines()
# print(file_abs,'is utf-8')
# except Exception as e:
# file_handler = open(file_abs, encoding='gbk', errors='ignore')
# lines = file_handler.readlines()
# print(file_abs,'is gbk=====================')
使用python转换编码格式
import chardet
import sys
import codecs def findEncoding(s):
file = open(s, mode='rb')
buf = file.read()
result = chardet.detect(buf)
file.close()
return result['encoding'] def convertEncoding(s):
encoding = findEncoding(s)
if encoding != 'utf-8' and encoding != 'ascii':
print("convert %s%s to utf-8" % (s, encoding))
contents = ''
with codecs.open(s, "r", encoding) as sourceFile:
contents = sourceFile.read() with codecs.open(s, "w", "utf-8") as targetFile:
targetFile.write(contents) else:
print("%s encoding is %s ,there is no need to convert" % (s, encoding)) if __name__ == "__main__":
if len(sys.argv) != 2:
print("error filename")
else:
convertEncoding(sys.argv[1])
debug:
with codecs.open('/tmp/slowlog3','w', encoding='utf-8') as targetFile:
targetFile.write(contents) with codecs.open('/data/usr/src/app/dbmanager/slowlogs/DB-mobile01_10.21.6.84_3306_2019-05-30.slowlog', encoding='utf-8', errors='ignore') as sourceFile:
with codecs.open('/data/usr/src/app/dbmanager/slowlogs/DB-mobile01_10.21.6.84_3306_2019-05-30.slowlog', encoding='utf-8') as sourceFile:
contents = sourceFile.read() chardet.detect(file) /data/usr/src/app/dbmanager/slowlogs/p.data.hadoop.bitool.config_10.11.9.42_3306_2019-05-19.slowlog >>> file = open('/data/usr/src/app/dbmanager/slowlogs/p.data.hadoop.bitool.config_10.11.9.42_3306_2019-05-19.slowlog', 'rb').read()
>>> result = chardet.detect(file)
>>> result['encoding']
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
对文件操作流程
打开文件,得到文件句柄并赋值给一个变量
通过句柄对文件进行操作
关闭文件
打开文件的模式有:
r,只读模式(默认模式)打开文件。文件的指针将会放在文件的开头。【无法创建文件,用r权限打开一个不存在文件会报错】
w,只写模式。如果文件已存在则将其清空【不可读;不存在则创建;存在则覆盖原文件;】
x ,不存在,创建;存在,报错;只写
a,打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
r+,打开一个文件用于读写。文件指针将会放在文件的开头。【用的最多】
w+,写读,如果文件已存在则将其覆盖,不存在则创建新文件【先创建一个文件再往里写,会覆盖原文件内容,了解,少用】
a+,打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写【追加,读,写】(在python2.x中a+会覆盖字符,py3.x中只能在文件末尾追加)
小结:
上面三种 用的最多的就是r+,r+读写追加到末尾,w+写读覆盖
r+ ,读写:
读:指针为0,从0开始读
写:如果写之前,有过读操作,则在最后追加
主动seek,写从当前指针向后写
a+ ,读写:
读:最后位置读取
写:
最后追加
主动seek后,依然最后追加
"b"表示处理二进制文件,(处理方式是二进制,但打印出来的并非是0101形式)(如:视频文件,FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
rb
wb
ab
二进制用在:socket编程中,传输数据只能用二进制模式(py3.0中,2.0支持字符)
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
rU
r+U
readline默认读一行,单行读,如果需要读指定行数,在循环中加判断即可,readlines:把文件读进列表,全读,每行成为一个元素
文件处理方法1:(以/etc/passwd为例) 打印文件:
f = open('yes.txt', 'r+',encoding='utf-8')
for line in f.readlines():
print(line.strip()) 不打印第十行:注意enumerate的用法
f = open('yes.txt', 'r', encoding='utf-8')
for index,line in enumerate(f.readlines()):
if index == 9:
pass #此处也可用continue
else:
print(line.strip()) 上面的readlines处理大文件不用,它会把文件全部加载进内存
读大文件用下面方法:(读一行,覆盖上一行的内存位置,类似迭代器原理)
f = open('yes.txt', 'r', encoding='utf-8')
count = 0
for i in f:
count += 1
if count == 10:
print('---------------------------------')
continue
print(i.strip())
此方法处理大文件效率最高 tell、seek的用法
tell 是打印指针所在字符的位置。
read,一次读多少个字符
readline一次读一行 f = open('yes.txt', 'r', encoding='utf-8')
print(f.tell())
输出 0
f = open('yes.txt', 'a+', encoding='utf-8')
print(f.tell())
输出 1664 seek(0)回到最开始字符的位置,(tell和seek搭配使用),seek:从seek到的位置到第一个换行符的字符打印出来,之前如果有字符将被舍弃
f = open('yes.txt', 'r', encoding='utf-8')
print(f.encoding) #获取文件的编码 flush方法:把write的内容实时同步到硬盘上
应用举例:进度条的实现:
import sys,time
for i in range(20):
sys.stdout.write('#')
sys.stdout.flush()
time.sleep(0.1)
如果不加flush,会等程序执行完后再一次性写入硬盘(再输出到屏幕)。 截断:truncate(truncate vt. 把…截短)
truncate(100):表示截取后只保留前100个字节 truncate举例: file = open('mage1.txt', 'w+')
for i in range(1, 11):
file.write('this is %i line\n' %i)
file.truncate(3)
file.seek(0)
print(file.tell()) #查看指针位置在文件尾部
print(file.readlines())
#执行write方法之后,光标已经位于文件尾部,readlines的值为空,必须移动光标到文件开头,即seek(0),readlines才会有值 #截取文件内容到当前指针所在处:
file.truncate(file.tell()) seek移动光标无效,truncate从头开始截断 文件修改:
修改思路:
1.vim编辑的方法,先把文件全部加载到内存,修改后再同步到硬盘
2.创建一个新的文件,从旧文件中读,加入判断修改,再写到新文件中
例:注意replace方法的使用
f = open('yesterday', 'r', encoding='utf-8')
f_new = open('yesterday.bak', 'w', encoding='utf-8') for line in f:
if '有那么多肆意的快乐等我享受' in line:
f_new.write('有那么多肆意的快乐等whitesky享受\n')
else:
f_new.write(line)
f.close()
f_new.close() 方法2:
f = open('yesterday', 'r', encoding='utf-8')
f_new = open('yesterday.bak', 'w', encoding='utf-8') for line in f:
if '有那么多肆意的快乐等我享受' in line:
line = line.replace('有那么多肆意的快乐等我享受', '有那么多肆意的快乐等whitesky享受')
f_new.write(line)
f.close()
f_new.close() with语句 为了避免打开文件后忘记关闭,可以通过管理上下文,即: with open('log','r') as f: 如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。 在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即: with open('log1') as obj1, open('log2') as obj2:
pass 例:注意换行(python规范:每行不超过80字符)写法:
with open('yesterday', 'r', encoding='utf-8') as f, \
open('yesterday.bak', 'w', encoding='utf-8') as f_new:
for line in f.readlines():
if '有那么多肆意的快乐等我享受' in line:
line = line.replace('有那么多肆意的快乐等我享受', '有那么多肆意的快乐等whitesky享受')
f_new.write(line)
import subprocess def get_ptquery_result(cdbip,conn_user,pwd):
ret = subprocess.run( '/usr/bin/pt-query-digest --processlist {} --user={} --password="{}" --port=3307 --run-time=10 --outliers Query_time:0.01:1000'.format(
cdbip,conn_user,pwd), stdout=subprocess.PIPE, shell=True, timeout=20)
# print('ret--------------------',ret)
print('result======================\n',
ret.stdout.decode(encoding="utf-8"))
# with open('/tmp/b.txt', 'w+') as a:
# a.write(ret.stdout.decode(encoding="utf-8")) if __name__ == '__main__':
get_ptquery_result('10.1.3.127', 'root', 'tangcaijun')
字符编码与转换:
计算机最初编码ascii码,但是 不能存中文,只能存英文或特殊字符(英文字符占一个字节8位)
-----》1980年出来个gb2312(只能存7000多汉字)
--------》95年出来个gb18030(存2万多汉字)
--------》现在出来个gbk(windows中文的默认字符编码)
向上兼容--gbk兼容gb2312(windows默认编码gbk)
各个国家都有各自的字符编码,导致中国的软件放日本看乱码,为了解决跨国家的语言支持问题,
ISO搞了个----Unicode(中英文默认都占两个字节即16位),兼容各个国家语言的编码
但是过于浪费空间-------
又出来个UTF8,默认英文字符依然都按ascii码的形式存储,中文统一占3个字节
小结:python程序中所有不同字符集的转换都要经过unicode(中转,万能翻译)
在python2默认编码是ASCII, python3里默认是unicode(支持中文,所以不必在开头加utf-8声明了)
例:gbk转utf-8----》gbk-decode->unicode-encode->utf-8
例:
python2中:
#-*-coding:utf-8-*-
__author__ = 'Alex Li'
import sys
print(sys.getdefaultencoding())
msg = "我爱北京*"
msg_gb2312 = msg.decode("utf-8").encode("gb2312") #默认decode解码为unicode(中转,你懂得)
gb2312_to_gbk = msg_gb2312.decode("gbk").encode("gbk")
print(msg)
print(msg_gb2312)
print(gb2312_to_gbk)
输出:
ascii
我爱北京*
�Ұ������찲��
�Ұ������찲��
python3中:
#-*-coding:gb2312 -*- #这个也可以去掉
__author__ = 'Alex Li'
import sys
msg = "我爱北京*"
#msg_gb2312 = msg.decode("utf-8").encode("gb2312")
msg_gb2312 = msg.encode("gb2312") #默认就是unicode,不用再decode,喜大普奔
gb2312_to_unicode = msg_gb2312.decode("gb2312")
gb2312_to_utf8 = msg_gb2312.decode("gb2312").encode("utf-8")
print(sys.getdefaultencoding())
print(msg)
print(msg_gb2312)
print(gb2312_to_unicode)
print(gb2312_to_utf8)
输出:
utf-8
我爱北京*
b'\xce\xd2\xb0\xae\xb1\xb1\xbe\xa9\xcc\xec\xb0\xb2\xc3\xc5'
我爱北京*
b'\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\xe4\xba\xac\xe5\xa4\xa9\xe5\xae\x89\xe9\x97\xa8'
默认编码:
python3: unicode
python2: ASCII
In Python , all strings are considered Unicode by default. The unicode type from Python is called str in Python , and str becomes bytes.
在Python 3中,默认情况下所有字符串都被视为Unicode。Python 2中的Unicode类型在Python 3中称为str,str变成字节。
https://docs.djangoproject.com/en/1.11/topics/python3/
函数
局部变量:
1.函数中的变量称为局部变量,作用域只在函数中生效,除非强制声明 global var;
2.不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响;
3.局部变量的作用:为了临时保存数据需要在函数中定义变量来进行存储; 全局变量:
在整个程序中都生效的变量,在程序的顶层定义的变量,既能在一个函数中使用,也能在其他的函数中使用; 注意:
1.生产中不要在函数中定义或更改全局变量,很难调试(函数可能在程序多处调用,改动之后逻辑混乱)【如果在函数中修改全局变量,那么就需要在修改前使用global 进行声明】
2.全局变量和局部变量名字相同时,局部变量的值会覆盖全局变量的值(强龙不压地头蛇)
3.字符串和数字在函数外定义,视为全局变量,在函数体内不能修改,列表和字典在函数外定义,在函数体内可以修改 函数return返回值的应用:
return作用(return 的后面可以是数值,也可是一个表达式):
1.返回值
2.结束函数,函数体中遇到return将不再往下运行
计算1~num的累积和
def calculate(num):
result = 0
count = 1
while count <= num:
result += count
count += 1
return result
result = calculate(100)
print(result) 函数返回多个值
def multi_return_val():
return 100, 200 print(multi_return_val())
输出:(100, 200) #本质是利⽤了元组 函数嵌套应用
1. 写一个函数打印一条横线
2. 打印自定义行数的横线 def print_line():
print('------------------') def print_num_line(num):
for i in range(int(num)):
print_line() print_num_line(10) 1. 写⼀个函数求三个数的和
2. 写⼀个函数求三个数的平均值
def sum3num(a, b, c):
return a+b+c def cal_aver(a, b, c):
outcome = sum3num(a, b, c)
aver_out = outcome/3
return aver_out result = cal_aver(27, 27, 27)
print('average is %d' % result) 函数参数:
位置参数调用:与形参一一对应
关键字参数(关键字参数特点:带等号)调用:与形参顺序无关
记住一句话:关键字参数一定放在后边,不能写在位置参数之前,
顺序: def test_args(位置参数 -- 关键字参数 -- 默认参数 -- 可变参数(*arg,**arg)): 注意:*arg收集位置参数,**arg收集关键字参数 一:默认参数(缺省参数)
特点:可有可无
用途:
1.默认安装值(类似装软件时的一键安装的默认参数)
2.在一个连接数据库的函数中,可以设定默认端口 def printinfo(userID,servername='test_01',port=3306):
print('userID:', userID)
print('servername', servername)
print('port', port) printinfo(userID='3', servername='whisky')
print('\nthe following use default value:')
printinfo(userID='666') 输出:
userID: 3
servername whisky
port 3306 the following use default value:
userID: 666
servername test_01
port 3306 注意:带有默认值的参数⼀定要位于参数列表的最后⾯,否则报错:SyntaxError: non-default argument follows default argument 参数组(不定长参数):说白了就是批量传参(加了星号(*)的变量args会存放所有未命名的变量参数,args为元组;⽽加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典)
作用:(把所有不固定的实参变成一个元组)函数在定义时没想好具体传几个参数,方便业务扩展
*args:接收N个位置参数传参转换成元组的形式(接收不到关键字参数)
**kwargs:接收N个关键字参数,转换成字典的形式(注意下它的两种传参方式) 元组和字典的传参方法:
def fun(a, b, *args, **kwargs):
print('a = ', a) # 取传递到函数中的字典中的值
print('b = ', b)
print('args = ', args)
print('kwargs = ', kwargs)
for key, value in kwargs.items():
print(key, "=", value) c = (3, 4, 5)
d = {"m":6, "n":7, "p":8}
fun(1, 2, *c, **d) # 注意元组与字典的传参方式
上面三行输出结果等同于fun(1, 2, 3, 4, 5, m=6, n=7, p=8) fun(1, 2, c, d) # 注意不加星号与上面的区别(传参时,带*表示传入元组,带**表示传入字典) 输出:
a = 1
b = 2
args = (3, 4, 5)
kwargs = {'m': 6, 'p': 8, 'n': 7}
m = 6
p = 8
n = 7 a = 1
b = 2
args = ((3, 4, 5), {'m': 6, 'p': 8, 'n': 7})
kwargs = {} **kwargs:把N个关键字参数,转换成字典的方式:
def test1(*kwargs):
print(kwargs) test1(*(1, 2, 3)) # 输出(1, 2, 3)
#等同于
tuple = (1, 2, 3) # 定义一个元组
test1(*tuple) # 输出(1, 2, 3) def test2(**kwargs):
print(kwargs)
print(kwargs['port']) # 取传递到函数中的字典中的值
print(kwargs['user'])
print(kwargs['ip'])
dicto = {'port': 80, 'user': 'root', 'ip': '192.168.2.1'}
test2(**dicto)
# 等同于
test2(port=80, user='root', ip='192.168.2.1')
# 等同于
test2(**{'port': 80, 'user': 'root', 'ip': '192.168.2.1'}) # 三次函数调用输出结果一致:
# {'ip': '192.168.2.1', 'port': 80, 'user': 'root'}
# 80
# root
# 192.168.2.1 递归函数(嵌套函数,多次调用自身):
例1:
def calc(n):
print(n)
if n < 10: # 限制条件,防止无限递归
return calc(n+1)
calc(0)
例2:求阶乘
def calc(num):
if num > 1:
result = num * calc(num-1)
else:
result = 1
print(num)
print(result)
return result ret = calc(3)
print(ret)
# 输出斐波那契数列第十个数字
# 0 1 1 2 3 5 8 13 21 34 55 89 def func(count, a, b):
if count == 10:
return b
c = a + b
a = b
b = c
return func(count+1, a, b) r = func(1, 0, 1)
print(r) '''
1 0 1
2 1 1
3 1 2
4 2 3
5 3 5
6 5 8
7 8 13
8 13 21
9 21 34
10 34 55
11 55 89
'''
递归小结:不断的调用自身,函数逐层调用自身(此时函数不退出),再逐层返回
匿名函数
用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤 lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression a = lambda arg1, arg2: arg1 * arg2 print('value is: ', a(2, 3333)) 匿名函数应用:
1.作为内置函数的参数 例:给出一个字典,分别按名字,年龄排序
stus = [
{"name": "zhangsan", "age": 18},
{"name": "lisi", "age": 19},
{"name": "wangwu", "age": 17}
]
name = lambda n: n['name']
age = lambda n: n['age'] stus.sort(key=name)
print('sort by name: ', stus)
#输出:sort by name: [{'age': 19, 'name': 'lisi'}, {'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}] stus.sort(key=age)
print('sort by age: ', stus)
#输出:sort by age: [{'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}, {'age': 19, 'name': 'lisi'}] 2.自己定义函数
例:
def fun(a, b, c):
print('a: ', a)
print('b: ', b)
print('result: ', c(a, b, 8)) fun(2, 3, lambda i, j, g: i**j+g) 输出:
a: 2
b: 3
result: 16
l = [(lambda x: x*2), lambda y: y*3]
for i in l:
print(i(4))
stus = [
{"name": "zhangsan", "age": 18},
{"name": "lisi", "age": 19},
{"name": "wangwu", "age": 17}
]
name = lambda n: n['name']
age = lambda n: n['age'] for i in name: lambda 还是有以下优势的:
1. 省去定义函数的过程,快速定义单行的最小函数,让代码更加精简
2. 不需要复用的函数,无须定义函数名称
3. 和 filter map reduce 结合使用 补充:
不带参数的lambda表达式:
lambda:x 相当于
def xo():
return x
# 不带参数的lambda: def count():
fs = []
for i in range(1, 4):
def f(i):
return lambda : i*i
fs.append(f(i))
return fs f1, f2, f3 = count()
print(f1(), f2(), f3()) def f(i):
return lambda: i * i a = f(2)
print(a())
def lam():
return 6666 a = lambda : lam() print(a()) #
filter 函数:
filter 函数会对指定序列执行过滤操作,filter(function or None, sequence) -> filter object (list, tuple, or string in 2.x)
filter 函数会对序列(如列表)参数 sequence 中的每个元素调用 function 函数,最后返回的结果包含调用结果为True的元素
注意:3.x 返回的是一个filter object (后续的函数map也是返回object),要加上list()等类型转换;而之前 2.x 版本的返回值类型和参数sequence的类型相同 例1:
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
l1 = filter(lambda x: x % 2 == 0, l)
l1 = list(filter(lambda x: x % 2 == 0, l)) # 在此处可以直接转换filter函数的结果
print(list(l1)) 输出:[2, 4, 6, 8, 10]
例2:
def f1(x):
if x >22:
return True
else:
return False
ret = filter(f1,[11,22,33]) #调用函数对象,并非执行函数,所以f1无需加括号
# 默认处理结果返回是一个类,需要迭代打印,因为浪费内存。 可以用next迭代取值。 或者for循环 循环依次取出
print(next(ret))
print(list(ret))
filter的实现原理:
#filter 实现
def myfilter(fuc,seq):
new_li = []
for i in seq:
#print(i)
ret = fuc(i)
if ret:
new_li.append(i)
return new_li
def f1(x):
if x > 22:
return True
else:
return False
li = [11,22,33,44]
new=myfilter(f1,li)
print(new)
map 函数
map 函数会对指定序列做映射操作,map(function or None, sequence) -> map object (list, tuple, or string in 2.x)
map 函数会对序列参数 sequence 中的每个元素调用 function 函数,返回的结果为每一个元素调用function函数的返回值
l = [1, 2, 3]
l = list(map(lambda x: x**2, l))
print(l)
输出:[1, 4, 9] 实现原理:
def mymap(func, seq):
li = []
for i in seq:
ret = func(i)
li.append(ret)
print(li) mymap(lambda x: x + 100, [1, 2, 3])
#输出:[101, 102, 103]
例:
li = [11, 22, 33, 44] def x(arg):
return arg + 100 r = map(x, li) # 在python 2.x中,直接print r 输出结果,py3 中返回一个迭代器对象
for i in r:
print(i)
输出:111 122 133 144
reduce 函数
注意:reduce 函数在 3.x 版本不是内建函数了,reduce()函数已经被从全局名字空间里移除了,它现在被放置在fucntools模块里,用的话要 先引入
from functools import reduce
reduce 函数会对指定序列做迭代操作,reduce(function, sequence[, initial]) -> value
reduce 函数中的function参数是一个有两个参数的函数,reduce依次从 sequence 中取一个元素,和上一次调用 function 的结果做参数再次调用function。
reduce() 函数会对参数序列中元素进行累积。 函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。 reduce() 函数语法: reduce(function, iterable[, initializer]) function -- 函数,有两个参数
iterable -- 可迭代对象
initializer -- 可选,初始参数 >>>def add(x, y) : # 两数相加
... return x + y
...
>>> reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5
15
>>> reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
15
# reduce应用: # 列表中的字典去重: def tes(x, y):
print x, y , ' x ----------y'
if y in x: # in 只能判断 列表中 或 字典的key中 是否存在指定元素
print y
return x
else:
print '------------', x + [y] # y是列表中的一个元素(字典)
return x + [y] def remove_duplicate(data_list):
data_list = [{'bk_cloud_id': '', 'bk_host_innerip': '10.51.3.2'}, {'bk_cloud_id': '', 'bk_host_innerip': '10.51.3.2'}, {'bk_cloud_id': '', 'bk_host_innerip': '10.51.3.2222'}]
run_function = lambda x, y: x if y in x else x + [y]
return reduce(tes, [[], ] + data_list) # reduce只负责按序取元素
## python in关键字的用法:
# in 只能判断 列表中 或 字典的key中 是否存在指定元素
>>> x
[{'bk_cloud_id': '', 'bk_host_innerip': '10.51.3.2'}]
>>> y
{'bk_cloud_id': '', 'bk_host_innerip': '10.51.3.2'}
>>> x = {'bk_cloud_id': '', 'bk_host_innerip': '10.51.3.2'}
>>> if y in x:
... print 111
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
from functools import reduce # 3.x 版本须引入
def sum(x,y):
return x+y
l = [1, 2, 3, 4, 5, 6]
l = reduce(sum, l)
print(l) # 结果21 结合lambda
from functools import reduce l = [1, 2, 3, 4, 5, 6]
l = reduce(lambda x, y: x+y, l)
print(l) # 结果21
help(reduce)
1 首先介绍一下 sorted() 函数: 输入代码:print(help(sorted)), 查看函数用法 输出为:
Help on built-in function sorted in module builtins: sorted(iterable, key=None, reverse=False)
Return a new list containing all items from the iterable in ascending order.
A custom key function can be supplied to customize the sort order, and the
reverse flag can be set to request the result in descending order.
sorted(iterable, key=None, reverse=False) , 返回一个有序的列表 iterable , 一个可以迭代的对象 key , 用来比较的对象,可以省略 reverse , 指定是否颠倒,即是否逆序,默认是正序, 可以省略 2 使用 sorted 对字典排序,注意字典的键key值都是同类型的 test = {1: "a", 3: "d", 6: "g", 2: "c", 5: "e", 0: "f", 4: 'b'} # 对字典的key值列表排序,返回列表 print(sorted(test.keys())) # 对字典的键值对元组列表排序,按元组的第1个元素排序,也就是 key # 返回的是一个元组列表 print(sorted(test.items(), key=lambda obj: obj[0])) # 对字典的键值对元组列表排序,按元组的第2个元素排序,也就是 value
# 返回的是一个元组列表
print(sorted(test.items(), key=lambda obj: obj[1])) 输出结果为:
[0, 1, 2, 3, 4, 5, 6]
[(0, 'f'), (1, 'a'), (2, 'c'), (3, 'd'), (4, 'b'), (5, 'e'), (6, 'g')]
[(1, 'a'), (4, 'b'), (2, 'c'), (3, 'd'), (5, 'e'), (0, 'f'), (6, 'g')] 如果要反序,添加 reverse=True 即可, 如:sorted(test.keys(), reverse=True) 3 使用 OrderedDict 对字典排序
from collections import OrderedDict test = {1: "a", 3: "d", 6: "g", 2: "c", 5: "e", 0: "f", 4: 'b'} # 普通 dict 插入元素时是无序的,使用 OrderedDict 按元素插入顺序排序 # 对字典按key排序, 默认升序, 返回 OrderedDict def sort_key(old_dict, reverse=False): """对字典按key排序, 默认升序, 不修改原先字典""" # 先获得排序后的key列表 keys = sorted(old_dict.keys(), reverse=reverse) # 创建一个新的空字典 new_dict = OrderedDict() # 遍历 key 列表 for key in keys: new_dict[key] = old_dict[key] return new_dict # 对字典按 value 排序,默认升序, 返回 OrderedDict def sort_value(old_dict, reverse=False): """对字典按 value 排序, 默认升序, 不修改原先字典""" # 获取按 value 排序后的元组列表 items = sorted(old_dict.items(), key=lambda obj: obj[1], reverse=reverse) # 创建一个新的空字典 new_dict = OrderedDict() # 遍历 items 列表 for item in items: # item[0] 存的是 key 值 new_dict[item[0]] = old_dict[item[0]] return new_dict print(sort_key(c)) print(sort_value(c)) 输出结果为: OrderedDict([(0, 'f'), (1, 'a'), (2, 'c'), (3, 'd'), (4, 'b'), (5, 'e'), (6, 'g')]) OrderedDict([(1, 'a'), (4, 'b'), (2, 'c'), (3, 'd'), (5, 'e'), (0, 'f'), (6, 'g')]) 使用 OrderedDict 可以保证元素按插入顺序排序,如果修改上面函数: # 创建一个新的空字典 new_dict = {} 这样创建的就是一个普通字典,虽然之前已经对key或value排好序了,但是插入的时候还是无序的,所以没作用。 简化使用 OrderedDict : from collections import OrderedDict test = {1: "a", 3: "d", 6: "g", 2: "c", 5: "e", 0: "f", 4: 'b'} print(OrderedDict(sorted(test.items(), key=lambda obj: obj[0]))) print(OrderedDict(sorted(test.items(), key=lambda obj: obj[1]))) 输出结果还是和之前一样: OrderedDict([(0, 'f'), (1, 'a'), (2, 'c'), (3, 'd'), (4, 'b'), (5, 'e'), (6, 'g')]) OrderedDict([(1, 'a'), (4, 'b'), (2, 'c'), (3, 'd'), (5, 'e'), (0, 'f'), (6, 'g')])
http://python.jobbole.com/85124/