美文网首页
Python 切片、迭代、装饰器

Python 切片、迭代、装饰器

作者: 樗云 | 来源:发表于2019-12-06 16:44 被阅读0次

切片

  • str、list、tuple均可切片,返回类型和原来相同
  • 取出从m项开始的n个元素,每s个取一个
  • 省略m则为0,省略n则为到最后一个为止,省略:s
  • 若全省略则L[:],等于拷贝
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)
迭代目标
  • dict等迭代的是key。
    如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()
  • list等迭代的是元素
    如果要迭代下标,可以用``
for i, value in enumerate(["A","B","C"]):
    print(i, value)
  • 对于value或元素,也可以同时迭代两个(类似ES6解构赋值)
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
  • 通过next()for循环执行
  • 超出长度继续执行时会报StopIteration错误
  • 既属于Iterable又属于Iterator
  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

  • 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
  • Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算,因此节约内存空间,甚至可以表示一个无限大的数字流(如全体自然数)
  • 使用iter()函数为listdictstrIterable添加Iterator
myIter=iter('abc')
print(next(myIter),next(myIter),next(myIter))#a b c

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

  • 通过list()等可以把Iterator转化回非Iterator

处理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中已经废弃

  • key
    只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse
    排序规则,reverse = True 降序 , reverse = False 升序(默认)。
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表达式)

  • Python对匿名函数的支持有限,通过关键字lambda表示匿名函数。
  • 匿名函数只能有一个表达式,不用写return,返回值就是该表达式的结果。
lambda x: x * x
def f(x):
    return x * x

装饰器

  • 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
  • 本质上,decorator就是一个返回函数的高阶函数。
无参数装饰器
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)

相关文章

网友评论

      本文标题:Python 切片、迭代、装饰器

      本文链接:https://www.haomeiwen.com/subject/vtkhgctx.html