摘要:用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。和不同的是,把传入的函数依次作用于每个元素,然后根据返回值是还是决定保留还是丢弃该元素。字符串给出当前平台使用的行终止符。程序中间的退出,为正常退出。
列表生成式
函数的参数类型
lambda函数
map, reduce, filter, sorted函数
eval, exec, join, zip函数
itertools中的函数
copy与deepcopy函数
模块
os、sys模块
迭代器
生成器
迭代器
参考网站:
Python3教程: https://www.python-course.eu/...
Python之函数参数的使用:https://blog.csdn.net/jclian9...
廖雪峰Python教程: https://www.liaoxuefeng.com/w...
Python之浅谈exec函数: https://blog.csdn.net/jclian9...
Python官网的itertools说明: https://docs.python.org/3.6/l...
Python-copy()与deepcopy()区别: https://blog.csdn.net/qq_3290...
copy模块官网:https://docs.python.org/3.5/l...
列表生成式列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。一般是利用原有的数据结构来生成新的列表。
# 利用range()生成[1,2,...,9,10] list(range(1,11)) # 生成[1x1, 2x2, 3x3, ..., 10x10] [x * x for x in range(1, 11)] # 可以通过占位符_代表列表中的元素 [_*_ for _ in range(1,11)] # 筛选出仅偶数的平方, 在for循环后加上if判断语句 [x * x for x in range(1, 11) if x % 2 == 0] # 利用占位符简化 [_*_ for _ in range(1, 11) if not _%2] # 两层循环,三层循环,.... [m + n for m in "ABC" for n in "XYZ"] [x+y+z for x in "ab" for y in "cd" for z in "ef"] # 遍历字典,生成列表 d = {"x": "A", "y": "B", "z": "C" } [k + "=" + v for k, v in d.items()]函数的参数类型
在Python中定义函数,其参数类型有:
位置参数
默认参数
可变参数
关键字参数
这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:位置参数、默认参数、可变参数和关键字参数。
可变参数以*开头,允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。关键字参数以**开头,允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个dict。若默认参数与可变参数放在一起,则接受完默认参数后,其后参数为可变参数。
位置参数位置参数指定名称的必须放在未指定名称的后面
def person(name,age,city): s = "info: name=%s, age=%s, city=%s"%(name,age,city) return s print(person("Jack", 25, "NY")) print(person(name="Jack", age=25, city="NY")) print(person("Jack", 25, city="NY")) # 下面的参数使用有误,位置参数指定名称的必须放在未指定名称的后面 print(person(name="Jack", 25, "NY"))默认参数
默认参数必须放在非默认参数的后面,可以该表默认参数的值
def person(name, city, age=18): s = "info: name=%s, age=%s, city=%s"%(name,age,city) return s print(person("Jack", "NY")) print(person("Jack", "NY", 20))可变参数
可变参数以*开头,允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。函数参数的长度是可以变化的, 例如内置的sum, min, max等
def var_sum(*args): sum = 0 for i in args: sum += i return sum print(var_sum(1,2,3)) print(var_sum(1,2,3,4)) # 利用*号来分解参数 print(var_sum(*[1,2,3,4,5]))
若位置参数或默认参数与可变参数放在一起,则接受完位置参数或默认参数后,其后参数为可变参数。
def var_sum(a, *args): sum = 0 for i in args: sum += i print("a is %s, sum is %s"%(a,sum)) var_sum(1,2) var_sum(1,2,3)关键字参数
关键字参数以**开头,允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个dict。
def test_args(**kwargs): print("-"*20) for key in kwargs: print("key:", key, ",value:", kwargs[key]) print() test_args(a=1,b=2) test_args(a=1,b=2,c=3)lambda函数
lambda函数即为匿名函数,用关键字lambda表示,冒号(:)前面的为参数,后面为返回值,不用写return.
如:
lambda x: x*x
匿名函数有个限制,就是只能有一个表达式,一般一行代码,不用写return,返回值就是该表达式的结果。
用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数,即函数也是变量,此为函数式编程(functional programming)思想。
f = lambda x: x*x f(5)map, reduce, filter, sorted函数 map函数
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
可以直接作用于for循环的对象统称为可迭代对象:Iterable.
举例说明,比如我们有一个函数f(x)=x^2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:
# map函数: 一一映射 def f(x): return x * x r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) list(r) # 利用lambda简化上述代码 list(map(lambda x: x*x, range(1, 11)))
再例如: 把list所有数字转为字符串:
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))reduce函数
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,一个是函数,一个是Iterable. reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方说对一个序列求和,就可以用reduce实现:
# 导入reduce, 这很重要 from functools import reduce def add(x, y): return x + y reduce(add, [1, 3, 5, 7, 9]) # 利用lambda函数简化 reduce(lambda x,y: x+y, range(1,10,2))
作业: 利用reduce将序列[1, 3, 5, 7, 9]转化为整数13579.
map, reduce的一个复杂例子:
将字符串列表["1", "3", "5", "7", "9"]转化为整数13579
from functools import reduce a = ["1", "3", "5", "7", "9"] t = reduce(lambda x,y: 10*x+y, map(int, a)) print(t)filter函数
Python内建的filter()函数用于过滤序列。
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
例如,在一个list中,删掉偶数,只保留奇数,可以这么写:
list(filter(lambda x: x%2 == 1, [1, 2, 4, 5, 6, 9, 10, 15]))sorted函数
Python内置的sorted()函数就可以对list进行排序。
sorted([36, 5, -12, 9, -21])
此外,sorted()函数还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:
sorted([36, 5, -12, 9, -21], key=abs) sorted(["bob", "about", "Zoo", "Credit"], key=str.lower, reverse=True)
高阶函数,就是让函数的参数能够接收别的函数。map, reduce, filter, sorted都是高阶函数。
join, zip, eval, exec函数 join函数Python中的join函数有两个,分别为: join()和os.path.join(),具体作用如下:
join(): 连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串
os.path.join(): 将多个路径组合后返回
字符串中的join()函数的使用方法:
"sep".join(seq)
sep:分隔符。可以为空。 seq:要连接的元素序列。 返回一个新的字符串。
seq = ["hello","good","boy","Dido"] print(" ".join(seq)) print("*".join(seq))zip函数
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
# basic use of zip x = [1, 2, 3] y = [4, 5, 6] zipped = zip(x, y) print(list(zipped)) # zip for loops for i,j in zip(x,y): print(i, "->", j) # unzip the list a = [(1,2,3), (3,4,5)] x2, y2, z2 = zip(*a) print(x2) print(y2) print(z2) # transpose a matrix mtx = [(1, 2), (3, 4), (5, 6)] print(list(zip(*mtx))) # clustering a data series into n-length groups idiom seq = range(1, 10) print(list(zip(*[iter(seq)]*3))) # dict and zip keys = ["spam", "eggs"] vals = [42, 1729] d = dict(zip(keys, vals)) print(d)eval函数
eval函数用来计算字符串表达式的值
t = eval("23") print(t) print(type(t)) print(eval("(1+2)*(3+4)"))exec函数
exec()是Python的内置函数,不同于eval()函数只能执行计算数学表达式的结果的功能,exec()能够动态地执行复杂的Python代码,能够十分强大。
简单例子:
# 执行简单的Python语句 i = 12 j = 13 exec("answer=i*j") print("Answer is %s"%answer) # 执行复杂的Python语句 func = "def fact(n): return 1 if n==1 else n*fact(n-1)" exec(func) a = fact(5) print(a)
exec函数还可以执行储存在其他文件中的Python代码,例如位于E盘的eg.txt,如下:
def fact(n): if n==1: return 1 else: return n*fact(n-1) t = fact(6) print(t)
利用exec函数执行eg.txt中的代码:
with open("E://eg.txt", "r") as f: s = f.read() exec(s)
还可以在exec()函数中加入参数,参数的传递可以写成字典(dict)形式。
x = 10 expr = """ z = 30 sum = x + y + z print(sum) """ def func(): y = 20 exec(expr) exec(expr, {"x": 1, "y": 2}) exec(expr, {"x": 1, "y": 2}, {"y": 3, "z": 4}) func()
输出结果为:
60itertools模块中的函数
33
34
Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数。
itertools模块提供的全部是处理迭代功能的函数,它们的返回值不是list,而是Iterator,只有用for循环迭代的时候才真正计算。
无穷迭代器Iterator | Arguments | Results | Example |
---|---|---|---|
count() | start, [step] | start, start+step, start+2*step, ... | count(10) --> 10 11 12 13 14 ... |
cycle() | p | p0, p1, ... plast, p0, p1, ... | cycle("ABCD") --> A B C D A B C D ... |
repeat() | elem [,n] | elem, elem, elem, ... endlessly or up to n times | repeat(10, 3) --> 10 10 10 |
Iterator | Arguments | Results | Example |
---|---|---|---|
accumulate() | p [,func] | p0, p0+p1, p0+p1+p2, ... | accumulate([1,2,3,4,5]) --> 1 3 6 10 15 |
chain() | p, q, ... | p0, p1, ... plast, q0, q1, ... | chain("ABC", "DEF") --> A B C D E F |
chain.from_iterable() | iterable | p0, p1, ... plast, q0, q1, ... | chain.from_iterable(["ABC", "DEF"]) --> A B C D E F |
compress() | data, selectors | (d[0] if s[0]), (d[1] if s[1]), ... | compress("ABCDEF", [1,0,1,0,1,1]) --> A C E F |
dropwhile() | pred, seq | seq[n], seq[n+1], starting when pred fails | dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 |
filterfalse() | pred, seq | elements of seq where pred(elem) is false | filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 |
groupby() | iterable[, keyfunc] | sub-iterators grouped by value of keyfunc(v) | |
islice() | seq, [start,] stop [, step] | elements from seq[start:stop:step] | islice("ABCDEFG", 2, None) --> C D E F G |
starmap() | func, seq | func(seq[0]), func(seq[1]), ... | starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 |
takewhile() | pred, seq | seq[0], seq[1], until pred fails | takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 |
tee() | it, n | it1, it2, ... itn splits one iterator into n | |
zip_longest() | p, q, ... | (p[0], q[0]), (p[1], q[1]), ... | zip_longest("ABCD", "xy", fillvalue="-") --> Ax By C- D- |
groupby()函数
groupby()把迭代器中相邻的重复元素挑出来放在一起:
for key, group in itertools.groupby("AAABBBCCAAA"): print(key, list(group)) A ["A", "A", "A"] B ["B", "B", "B"] C ["C", "C"] A ["A", "A", "A"]
实际上挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key。
另一个例子
# 按身高归类 from itertools import * def height_class(h): if h>180: return "tall" elif h<160: return "short" else: return "middle" friends = [191, 158, 159, 165, 170, 177, 181, 182, 190] for m,n in groupby(friends,key = height_class): print(m) print(list(n))
作业: 对于一组身高的数据(list),利用上面代码给出的身高标准,将所以的tall, short, middle归为一类。注意与groupby()函数的区别。
tee()函数
把一个迭代器分为n个迭代器, 返回一个元组.默认是两个
from itertools import * a = "hello" c, d, e = tee(iter(a), 3) for i, j, k in zip(c, d, e): print(i, j, k)组合生成器
Iterator | Arguments | Results |
---|---|---|
product() | p, q, ... [repeat=1] | cartesian product, equivalent to a nested for-loop |
permutations() | p[, r] | r-length tuples, all possible orderings, no repeated elements |
combinations() | p, r | r-length tuples, in sorted order, no repeated elements |
combinations_with_replacement() | p, r | r-length tuples, in sorted order, with repeated elements |
product("ABCD", repeat=2) | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD | |
permutations("ABCD", 2) | AB AC AD BA BC BD CA CB CD DA DB DC | |
combinations("ABCD", 2) | AB AC AD BC BD CD | |
combinations_with_replacement("ABCD", 2) | AA AB AC AD BB BC BD CC CD DD |
copy: 浅拷贝(shallow copy), deepcopy: 深拷贝(deep copy).
我们寻常意义的复制就是深复制,即将被复制对象完全再复制一遍作为独立的新个体多带带存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响。
而浅复制并不会产生一个独立的对象多带带存在,他只是将原有的数据块打上一个新标签,所以当其中一个标签被改变的时候,数据块就会发生变化,另一个标签也会随之改变。这就和我们寻常意义上的复制有所不同了。
对于简单的 object,用 shallow copy 和 deep copy 没区别
复杂的 object, 如 list 中套着 list 的情况,shallow copy 中的 子list,并未从原 object 真的「独立」出来。也就是说,如果你改变原 object 的子 list 中的一个元素,你的 copy 就会跟着一起变。这跟我们直觉上对「复制」的理解不同。
例子:
from copy import copy, deepcopy #origin 里边有三个元素:1,2,[3, 4] origin = [1, 2, [3, 4]] # cop1为浅拷贝,cop2为深拷贝 cop1 = copy(origin) cop2 = deepcopy(origin) # cop1是否与cop2内容相同 print(cop1 == cop2) # cop1是否与cop2为同一个引用 print(cop1 is cop2) # 改变origin中嵌套列表中的元素 origin[2][0] = "hey" # 查看输出 print(origin) print(cop1) print(cop2) # 改变origin中嵌套列表中的元素 origin[1] = "hello" # 查看输出 print(origin) print(cop1) print(cop2)
输出结果:
True模块
False
[1, 2, ["hey", 4]]
[1, 2, ["hey", 4]]
[1, 2, [3, 4]]
[1, "hello", ["hey", 4]]
[1, 2, ["hey", 4]]
[1, 2, [3, 4]]
在Python中,一个Python文件就是一个模块。
模块让你能够有逻辑地组织你的 Python 代码段。
把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。
一个简单的模块例子:
hello.py
def say_hello(name): s = "hello, %s!"%name return s
使用模块:
import module
from module import ...
import hello print(hello.say_hello("Lee")) from hello import say_hello print(say_hello("Jack"))os、sys模块 os模块
os模块包含普遍的操作系统功能。
os常用方法及属性os.sep 可以取代操作系统特定的路径分隔符。windows下为 “”
os.name字符串指示你正在使用的平台。比如对于Windows,它是"nt",而对于Linux/Unix用户,它是"posix"。
os.getcwd() 函数得到当前工作目录,即当前Python脚本工作的目录路径。
os.getenv() 获取一个环境变量,如果没有返回none
os.putenv(key, value) 设置一个环境变量值
os.listdir(path) 返回指定目录下的所有文件和目录名。
os.remove(path) 函数用来删除一个文件。
os.system(command) 函数用来运行shell命令。
os.linesep 字符串给出当前平台使用的行终止符。例如,Windows使用"rn",Linux使用"n"而Mac使用"r"。
os.curdir: 返回当前目录(".")
os.chdir(dirname): 改变工作目录到dirname
os.path常用方法:os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录。
os.path.existe()函数用来检验给出的路径是否真地存在
os.path.getsize(name):获得文件大小,如果name是目录返回0L
os.path.abspath(name):获得绝对路径
os.path.normpath(path):规范path字符串形式
os.path.split(path) :将path分割成目录和文件名二元组返回。
os.path.splitext():分离文件名与扩展名
os.path.join(path,name):连接目录与文件名或目录;使用“”连接
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路径
sys模块提供了一系列有关Python运行环境的变量和函数。
sys模块的常用方法sys.argv: 实现从终端向程序传递参数。
sys.exit([arg]): 程序中间的退出,arg=0为正常退出。
sys.getdefaultencoding(): 获取系统当前编码,一般默认为ascii。
sys.setdefaultencoding(): 设置系统默认编码,执行dir(sys)时不会看到这个方法,在解释器中执行不通过,可以先执行reload(sys),在执行 setdefaultencoding("utf8"),此时将系统默认编码设置为utf8。(见设置系统默认编码 )
sys.getfilesystemencoding(): 获取文件系统使用编码方式,Windows下返回"mbcs",mac下返回"utf-8".
sys.path: 获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到。
sys.platform: 获取当前系统平台。
sys.stdin, sys.stdout, sys.stderr: stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们
生成器通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
创建generator的办法:
把一个列表生成式的[]改成()
yield关键字
将列表的[]改成()的例子:# 列表生成式 L = [x * x for x in range(10)] print(type(L)) # 创建生成器 g = (x * x for x in range(10)) print(type(g)) # 获取下一个返回值 # 当没有更多元素时,会抛出StopIteration错误 print(next(g)) print(next(g)) print(next(g)) # for循环 for n in g: print(n)通过yield创建生成器
# 普通方法生成斐波拉契数列 # 前几个斐波拉契数 def fib1(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return "done" fib1(6) # 通过yield创建生成器 # 注意yield的执行流程 def fib2(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return "done" # 将生成器函数赋值给变量f f = fib2(6) print(type(f)) for n in f: print(n)
generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
generator执行流程的理解:def odd(): print("step 1") yield 1 print("step 2") yield(3) print("step 3") yield(5) o = odd() print(next(o)) print(next(o)) print(next(o))迭代器
可以直接作用于for循环的数据类型有以下几种:
集合数据类型,如list、tuple、dict、set、str等;
generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:==Iterable==。
可以使用isinstance()判断一个对象是否是Iterable对象:
from collections import Iterable # 判断空列表是否为Iterable对象 # True print(isinstance([], Iterable)) # 判断空集合是否为Iterable对象 # True print(isinstance({}, Iterable)) # 判断字符是否为Iterable对象 # True print(isinstance("abc", Iterable)) # 判断生成器是否为Iterable对象 # True print(isinstance((x for x in range(10)), Iterable)) # 判断数字否为Iterable对象 # False print(isinstance(100, Iterable))
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以使用isinstance()判断一个对象是否是Iterator对象:
from collections import Iterator # 判断生成器是否为Iterator对象 # True print(isinstance((x for x in range(10)), Iterator)) # 判断空列表是否为Iterator对象 # False print(isinstance([], Iterator)) # 判断空集合是否为Iterator对象 # False print(isinstance({}, Iterator)) # 判断字符串是否为Iterator对象 # False print(isinstance("abc", Iterator))
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/41821.html
摘要:正文总所周知,和根本就是两个东西,每次因为这个兼容性的问题都会把自己搞疯。提供了模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中测试一些新版本的特性。传送门不多,才个。 写在前面 我是在学习cs231n的assignment3的课程,发现里面的代码大量频繁出现了这个库,那我就很奇怪了,为什么有个future这个奇怪名字的库会出现呢?到底这个库又有什么用?下面就让我为...
摘要:返回非负随机数大于或等于零且小于的位带符号整数。返回一个指定范围内的随机数返回的随机数的下界随机数可取该下界值。其中参数是下限,参数是上限,生成的随机数。如,结果相当于从序列中获取一个随机数。 你真的懂随机数? Author : Jasper YangSchool : Bupt Q:为什么要写这篇文章?A:因为我发现在最近的科学计算中,常常遇到随机数,所有的随机数都是基于0,1随机,而...
摘要:很简单,这个模块实现了开辟一块共享内存空间,就好比中的方法一样,有兴趣的同学可以去查阅。查了下资料,返回的对象控制了一个进程,可用于多进程之间的安全通信,其支持的类型有和等。 有关于 multiprocessing 中共享变量的问题 现在的cpu都很强大,比方我用的至强2620有24核可以同时工作,并行执行进程程序。这在计算密集型的程序是很需要的,如沙漠中的绿洲,令人重获新生。那么,问...
摘要:在第一次执行循环时该变量为是一个布尔值在最后一次执行循环时被置为。注册自定义修改显示字段管理后台默认显示,在中添加返回值方法,修改显示效果。 理解上下文 render(request,x.html,context) request:请求的固定写法。 x.html:模板,需要填补丁的模板。 context:上下文,填充模板的补丁。 模板的使用流程 写模板,创建Template对象,用...
阅读 3700·2023-04-25 18:41
阅读 1135·2021-11-11 16:55
阅读 1755·2021-09-22 15:54
阅读 3012·2021-09-22 15:51
阅读 3512·2019-08-30 15:55
阅读 1894·2019-08-30 14:19
阅读 1245·2019-08-29 10:57
阅读 1671·2019-08-29 10:56