Python 切片、迭代、装饰器

2019-12-06  本文已影响0人  樗云

切片

newL=L[m:n(:s)]

len()

len()函数可以获得list/tuple元素的个数、dict键值对的个数、str字符数、bytes字节数

迭代 Iterable

listtuplestrbytesdictrangegeneratorset为可迭代对象,因此可以使用for...in进行迭代

判断是否为可迭代对象
from collections.abc import Iterable
isinstance([1,2,3], Iterable)
迭代目标
for i, value in enumerate(["A","B","C"]):
    print(i, value)
for x, y in [(1, 1), (2, 4), (3, 9)]:
    print(x, y)

生成列表

range

range(num)range(startNum,endNum)(有头无尾)生成range类型,再通过list()转换成列表

列表生成式
[<执行操作> for x in <可迭代对象> (<逻辑判断>)]

[x * x for x in range(1, 11) if x % 2 == 0]
#[4, 16, 36, 64, 100]
生成器 generator
  1. 直接定义
    类似列表生成式的方式,[]改为()
g = (x * x for x in range(10))
#print(next(g))
for n in g:
    print(n)
  1. 通过函数定义
    存在yield的函数视为generator函数,函数执行时仅返回一个generator对象,每次用next()调用该generator对象时执行函数,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
#next(fib(6))
for n in fib(6):
    print(n)

等同于ES6

function* fib(max) {
  var n = 0, a = 0, b = 1;
  while (n < max) {
    yield b;
    ({ a, b } = { a: b, b: a + b });
    n = n + 1;
  }

  return 'done'
}

//fib(6).next()
for (item of fib(6)) {
  console.log(item)
}

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

迭代器 Iterator

myIter=iter('abc')
print(next(myIter),next(myIter),next(myIter))#a b c

Python的for循环本质上就是通过先转换成Iterator再不断调用next()函数实现

处理Iterable的方法

不同于JS中只有数组可以使用,Python中Iterable均可使用以下方法

map

map将传入的函数依次作用到Iterable的每个元素,并把整体结果作为新的Iterator返回。

r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)//[1, 4, 9, 16, 25, 36, 49, 64, 81]

reduce

reduce把结果继续和Iterable的下一个元素做累积计算

from functools import reduce
def fn(x, y):
    return x * 10 + y
reduce(fn, [1, 3, 5, 7, 9])
# 13579

filter

filter把传入的函数依次作用于每个元素,根据返回值是True或False决定保留还是丢弃该元素,并把整体结果作为新的Iterator返回。

def is_odd(n):
    return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# [1, 5, 9, 15]

sorted

python2中可以使用cmp自定义排序规则,python3中已经废弃

sorted(iterable, key=None, reverse=False)  
L=[('b',2),('a',1),('c',3),('d',4)]
sorted(L, key=lambda x:x[1])

闭包

与JS相同,函数仅在调用时其中由函数外赋予的变量才会实际获得值,因此返回闭包时尽量不要引用任何循环变量,或者后续会发生变化的变量。如必须调用,需考虑函数嵌套

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
f1, f2, f3 = count()
f1()#1
f2()#4
f3()#9

匿名函数(lambda表达式)

lambda x: x * x
def f(x):
    return x * x

装饰器

无参数装饰器
def myDecorator(func):
    @functools.wraps(func) # wrapper.__name__ = func.__name__
    def wrapper(*args, **kw):
        ...
        func(*args, **kw)
        ...
    return wrapper

@myDecorator
def fun():
    ...
 # 等同于 fun = myDecorator(fun)
fun()
有参数装饰器
def myDecorator(param):
    def decorator(func):
        @functools.wraps(func) # wrapper.__name__ = func.__name__
        def wrapper(*args, **kw):
            ...
            func(*args, **kw)
            ...
        return wrapper
    return decorator

@myDecorator(param) 
def fun():
    ...
# 等同于 fun = myDecorator(param)(fun)
fun()

偏函数

用于为一个函数的某些参数设置默认值,并返回一个新的函数。

import functools
newFun = functools.partial(fun,*args,**kw)

等价于

def newFun(*args,**kw):
    return fun(*args,**kw)
上一篇 下一篇

猜你喜欢

热点阅读