高级特性

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

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. openmp学习心得(一)

    主要在vs2015下使用OMP,写一些自己omp的学习心得: 一.在VS2015下OpenMP的使用: 1.VS2015也仅仅支持OpenMP2.0版本,VS对OpenMP的支持并不太好. 2.在VS ...

  2. QMake(Qt项目构建)

    qmake工具能够简化不同平台上的项目构建.可以自动产生Makefiles文件,仅仅需要少量的信息就可以生成Makefile文件.同时qmake也可以构建不是Qt的项目.qmake基于项目文件中的信息 ...

  3. shell调用另一个脚本的三种方式fork/exec/source

    exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息. bash shell的命令分为两 ...

  4. [linux]centos7.4安装nginx

    下载nginx wget http://nginx.org/download/nginx-1.5.6.tar.gz 解压包安装在/opt/nginx. 目录下, 1.安装gcc(centos 7之后一 ...

  5. maven项目中 把依赖包打进jar包

    在pom.xml文件中增加build配置 1 <build> 2 <plugins> 3 <plugin> 4 <artifactId>maven-as ...

  6. part 36 AngularJS route reload

    In this video we will discuss angular route service reload() method. This method is useful when you ...

  7. Mac 下安装 MySQL 步骤

    安装 MySQL Mac 下安装MySQL推荐去官网下载dmg 版本的,我使用的版本是5.7.30. 如上图所示. 之后就是傻瓜式一键狂点不过需要注意的是,不要关闭下图所示的框框!不要关闭下图所示的框 ...

  8. jsonpath解析淘票票,所有购票的城市

    解决一些反爬,校验. 复制所有请求头 import urllib.request # 请求url url = 'https://dianying.taobao.com/cityAction.json? ...

  9. 菜鸡的Java笔记 国际化程序实现原理

    国际化程序实现原理 Lnternationalization        1. Locale 类的使用        2.国家化程序的实现,资源读取                所谓的国际化的程序 ...

  10. [noi712]练级

    先考虑一个联通块,可以发现这个联通快内不会存在两个偶数的点证明:如果存在,那么这两个点的某一条路径上的边全部反过来,可以使答案+2,即答案为点数或点数-1同时,发现答案的奇数点数一定与边数同奇偶,那么 ...