高级特性

代码不是越多越好,而是越少越好。代码不是越复杂越好,而是越简单越好。代码越少,开发效率越高。

1.切片

切片(Slice)操作符,取一个list或tuple的部分元素非常常见。

列表

L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
L[0:3]
L[1:3]
L[-1]
L[-2:] L=list(range(100) #0-99
L[:10] #前10
L[-10:] #后10
L[10:20]
L[:10:2] #前10,每两个取一个
L[::5] #所有数中每5个取一个

tuple

(0,1,2,3,4,5)[:3]  #得到的也是一个tuple(0,1,2)

字符串

'ABCDEFG'[:3]  #ABC
'ABCDEFG'[::2] #ACEG

不像R和Perl等专门提供字符串截取函数,Python中用一个切片操作就可完成,灵活使用能减少不少循环。

2.迭代iteration

通过for循环来遍历

d={'a':1, 'b':2, 'c':3}
for key in d: #字典默认迭代key
print(key) #无序 #迭代值
for value in d.values(): #括号不可少
print(value)
#迭代键和值
for k,v in d.items():

判断一个对象是否可迭代

from collections import Iterable
isinstance('abc',Iterable) #字符串可迭代
isinstance([1,2,3],Iterable) #list可迭代
isinstance(123,Iterable) #整数不可迭代

实现下标(元素索引)迭代循环

for i, value in enumerate(['a','b','c']):
print(i, value)

同时对多个变量循环

for x,y,z in [(1,2,3),(2,3,1),(2,1,3)]:
print(x,y,z)

任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环。

3.列表生成式

list(range(1,11))  #1..10

[x*x for x in range(1,11)]

[x*x for x in range(1,11) if x % 2 ==0]

[m+n for m in 'abc' for n in 'xyz']

应用

#列出当前目录所有文件和目录名
import os
[d for d in os.listdir('.')] #两个变量生成list
d={'x':1, 'y':2, 'z':3}
[k + '=' +v for k,v in d.items()] #所有list字符串小写
L=["aBC","Word"]
[s.lower() for s in L if isinstance(s,str)==True] #列表中只能都为str

4.生成器generator

一边循环一边计算。

创建生成器:

g=(x*x for x in range(10))  #()而非[]
g
next(g)
next(g)
...... #一个个打印出来,直到最后一个元素 for n in g: #可迭代
print(n)

用一个函数来实现generator。普通函数调用直接返回结果,生成器函数调用返回的是一个生成器对象。

#斐波那契数列
def fib(max):
n,a,b = 0,0,1
while n < max:
yield b #yield关键字
a,b = b,a+b
n = n+1
return 'done' for n in fib(6):
print(n) #不会返回return的值 #return的值包含在StopIteration错误的value中:
g=fib(6)
while True:
try:
x=next(g)
print('g:',x)
except StopIteration as e:
print('Generator return value:', e.value)
break

练习:写一个generator,不断输出杨辉三角的下一行

# _*_ coding: utf-8 _*_
def triangles():
L=[1]
yield L
while True:
#两端都是1,中间是上两个相邻数之和
L=[1]+[L[x]+L[x+1] for x in range(len(L)-1)]+[1]
yield L

5.迭代器

可迭代对象(Iterable):可直接作用于for循环的对象,一类是集合数据类型(list/tuple/dict/set/str),一类是generator(生成器和带yield的生成器函数)

#判断对象是否为Iterable对象,以下都为True
from collections import Iterable
isinstance([],Iterable)
isinstance({},Iterable)
isinstance('abc',Iterable)
isinstance((x for x in range(10)),Iterable)

可以被next()函数调用并不断返回下一个值的对象称为迭代器Iterator。

from collections import Iterator
isinstance([],Iterator) #False
isinstance({},Iterator) #False
isinstance('abc',Iterator) #False
isinstance((x for x in range(10)),Iterator) #True

生成器都是迭代器对象,list/dict/str虽然是可迭代对象,但不是迭代器。但它们可用iter()函数变成迭代器。

isinstance(iter([]),Iterator) #True
isinstance(iter('abc'),Iterator) #True

迭代器对象是一个数据流,它是惰性的,只能通过next函数按需计算下一步。

函数式编程

函数式编程是一种抽象程度很高的编程范式,纯函数式编程甚至没有变量(python不是)。其特点是允许把函数本身作为参数传入另一个函数,还允许返回一个函数。

1.高阶函数

变量可以指向函数

x=abs(-10) #赋值
x f=abs #赋函数
f
f(-10)

传入函数参数

def add(x,y,f):
return f(x)+f(y) add(-5,6,abs)

map/reduce

map(function,Iterable)

def f(x):
return x*x r=map(f,[1,2,3,4])
list(r) #简写
list([map(str,[1,2,3,4]))

reduce(f,[x1,x2,x3]) = f(f(x1,x2),x3)

from functools import reduce
def add(x,y):
return x+y reduce(add,[1,3,5,7,9])

map和reduce结合使用:

#字符串转化为整数函数
from functools import reduce
digits={'0':0,'1':1,'2':2,'3':3}
def str2int(s):
def fn(x,y):
return x*10+y
def char2num(s):
return digits[s]
return reduce(fn, map(char2num,s)) str2int('123')

以上函数还可进一步用lambda函数简化:

from functools import reduce
digits={'0':0,'1':1,'2':2,'3':3}
def char2num(s):
return digits[s]
def str2int(s):
return reduce(lambda x,y: x*10+y, map(char2num,s))

filter

过滤序列,从一个序列中筛出符合条件的元素

def is_odd(n):
return n % 2 == 1 list(filter(is_odd,[1,2,3,4,5])) #1,3,5

用filter筛选全体质数(素数):

#先构造一个从3开始的奇数序列
def _odd_iter():
n=1
while True:
n=n+2
yield n #然后定义一个筛选函数
def _not_divisible(n):
return lambda x: x%n > 0 #最后定义一个生成器,不断返回下个素数
def primes():
yield 2
it = _odd_iter() #初始序列
while True:
n=next(it) #返回第一个数
yield n
it = filter(_not_divisible(n),it) #构造新序列 #打印1000内的素数
for n in primes():
if n < 1000:
print(n)
else:
break

筛选回数:

def is_palindrome(n):
return str(n)==str(n)[::-1] output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))

sorted

排序算法

sorted([3,5,-23,4,-8])
sorted([3,5,-23,4,-8], key=abs) #按绝对值排序 sorted(['bob', 'about', 'Zoo', 'Credit']) #默认ASCII码['Credit', 'Zoo', 'about', 'bob']
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower) #['about', 'bob', 'Credit', 'Zoo'] sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) #反向 ['Zoo', 'Credit', 'bob', 'about']

用sorted()排序的关键在于实现一个映射函数。

2.返回函数

把函数作为结果值返回

def lazy_sum(*args):
def sum():
ax=0
for n in args:
ax=ax+n
return ax
return sum f=lazy_sum(1,2,5,7)
f #返回的是函数
f() #返回结果 #每次调用都会返回一个新的函数,即使参数相同也不一样
f1=lazy_sum(1,2,5,7)
f2=lazy_sum(1,2,5,7)
f1==f2 #False,f1()和f2()的调用结果互不影响。

闭包

上例中,在函数lazy_sum中又定义了函数sum,并且内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种程序结构称为“闭包(Closure)”。

返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs f1, f2, f3 = count()
#f1()f2()f3()都是9,因为返回的函数引用了变量i,但它并非立刻执行,等到3个函数都返回时,它们所引用的变量i已经变成了3。

如果一定要引用循环变量,就再创建一个函数,用该函数的参数绑定循环变量当前的值:

def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs

3.匿名函数

关键字lambda表示匿名函数

list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

#赋值变量
f = lambda x: x * x
f
f(5) #作为返回值
def build(x, y):
return lambda: x * x + y * y

4.装饰器

函数也是对象,可赋值给变量,并调用。

def now():
print('2019-1-1')
f=now
f()

函数对象的__name__属性可得到函数的名字:

now.__name__  #now
f.__name__ #now

想增加函数的功能,又不想修改函数的定义,这种在代码运行期间动态增加功能的方式称为“装饰器(Decorator)”。

本质上装饰器就是一个返回函数的高阶函数。

#定义一个能打印日志的装饰器:函数作为参数并返回函数
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper @log #把装饰器置于函数的定义处,相当于now = log(now)
def now():
print('2019-1-1') now() #调用函数,会打印日志

如果要自定义log文本,需要编写一个返回装饰器的高阶函数:

def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator #三层嵌套的装饰器调用:
@log('execute') #相当于now = log('execute')(now)
def now():
print('2015-3-25')

完整的装饰器写法:

import functools

def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper #带参数的装饰器:
import functools def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator

面向对象的装饰模式需要通过继承和组合来实现,Python的decorator可以用函数实现,也可以用类实现。

5.偏函数

functools模块提供的偏函数:当函数的参数个数太多化时,可创建一个新的函数,将某些参数给固定住(即设置默认值),从而在调用时更简单。

#自定义函数
def int2(x,base=2): #默认转化二进制
return int(x,base) #使用偏函数
import functools
int2 = functools.partial(int, base=2) #实际上固定了int()函数的关键字参数base
int2('10010')
int2('10010', base=10) max2 = functools.partial(max, 10) #10会作为*args的一部分自动加到左边
max2(5, 6, 7) #相当于max2(10,5, 6, 7)

Python基础笔记3的更多相关文章

  1. Python基础笔记系列十一:标准输入输出、文件读写和指针等操作

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 标准输入输出一.输入 在sublime中这个时候需要安装SublimeRE ...

  2. Python基础笔记系列一:基本工具与表达式

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 工具基础(Windows系统下)传送门:Python基础笔记系列四:工具的 ...

  3. 我的Python基础笔记

    Python是从刚开始参加工作,就有听各方面的测试大牛推崇,但是刚开始做测试时还是把基础的测试方法放在第一位来学习的,直到半年多以后才开始接触Python. 我的Python基础主要是以廖雪峰老师的在 ...

  4. Python基础笔记1

    这篇笔记来自廖雪峰的Python教程. 一.Python基础 Python使用缩进来组织代码块,务必遵守约定俗成的习惯,坚持使用4个空格的缩进. 在文本编辑器中,需要设置把Tab自动转换为4个空格,确 ...

  5. python基础笔记-0

    python中数据结构,主要有列表.元组.字典.集合. python中最基本数据结构是序列(sequence).序列中每个元素被分配一个序号——即元素位置,也成为索引.第一个索引是0,第二个是1,以此 ...

  6. Python基础笔记系列十四:python无缝调用c程序

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! python语言可以对c程序代码进行调用,以弥补python语言低性能的缺 ...

  7. Python基础笔记系列十三:socket网络编程

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!!使用python编写一个简易的服务端程序和客户端程序,启动服务端和客户端(监 ...

  8. Python基础笔记系列十二:requests模块的简单应用

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! httpbin httpbin这个网站能测试 HTTP 请求和响应的各种信 ...

  9. Python基础笔记系列十:模块

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 模块 #1.类比于java中的jar包,模块能让你能够有逻辑地组织你的Py ...

  10. Python基础笔记系列九:变量、自定义函数以及局部变量和全局变量

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 变量在前面的系列中也许就可以发现,python中的变量和C中的变量有些许不 ...

随机推荐

  1. BUAA2020软工作业(三)——个人项目

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 进一步提高自己的编码能力,工程能力 这个作业在哪个具体方面帮助 ...

  2. Ajax配合后端实现Excel的导出

    一.需求 在我们的日常开发中,可能经常需要遇到excel的导出,以往excel的导出服务器端都是使用的 GET 方法,但是某些情况下,服务器端只能使用 POST 方法,那么我们有没有好的方法实现exc ...

  3. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

  4. 2021.8.9考试总结[NOIP模拟34]

    T1 Merchant 如果$t=0$时不能达到$s$,那么所拿物品的价值一定关于时间单调递增,答案单调.因此可以特判$0$后二分. 用$sort$复杂度被卡,要用$\textit{nth_eleme ...

  5. 通过串口利用printf函数输出数据

    一.printf函数格式 printf函数具有强大的输出功能 %表示格式化字符串输出 目前printf支持以下格式的输出,例如: printf("%c",a);输出单个字符. pr ...

  6. Veritas Backup Exec™ 21.3 Multilingual (Windows)

    Backup Exec 21.3, Release date: 2021-09-06 请访问原文链接:https://sysin.org/blog/veritas-backup-exec-21-3/, ...

  7. pip切换源

    pip国内的一些镜像 阿里云http://mirrors.aliyun.com/pypi/simple/ 中国科技大学https://pypi.mirrors.ustc.edu.cn/simple/ ...

  8. Vue首屏性能优化组件

    Vue首屏性能优化组件 简单实现一个Vue首屏性能优化组件,现代化浏览器提供了很多新接口,在不考虑IE兼容性的情况下,这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情,当然为了考 ...

  9. JavaScript事件捕获冒泡与捕获

    事件流 JavaScript中,事件流指的是DOM事件流. 概念 事件的传播过程即DOM事件流.事件对象在 DOM 中的传播过程,被称为"事件流".举个例子:开电脑这个事,首先你是 ...

  10. C# WINFORM进销存系统开发(内涵免费源码+部分实操视频讲解)

    互联网的时代,电商火爆,大家都开始进行线上销售货品,那你是如何管理你的商品库存和进销问题?软积木--小敏用的是C# WINFORM进销存系统来管理我的数据,给我带来了很多便利. 它是高频需求项目,很多 ...