python学习21之高级特性

一、    高级函数补充

1. zip

把两个可迭代的内容生成一个可迭代的tuple元素类型组成的内容

l1=[1,2,3,4,5]
l2=[11,22,33,44,55]
z=[i for i in zip(l1,l2)]
print(z) #[(1, 11), (2, 22), (3, 33), (4, 44), (5, 55)]

2. enumerate

对可迭代对象里每一个元素,配上一个索引,然后索引和内容构成tuple类型

em=enumerate(l2)
l3=[i for i in em]
print(l3) #[(0, 11), (1, 22), (2, 33), (3, 44), (4, 55)]

3. collections模块

(1) namedtuple

tuple类型,是一个可命名的tuple

import collections
Point=collections.namedtuple("Point",['x','y']) #创建一个元组类
p=Point(11,22) #实例化一个元组
print(p.x) #访问元组的x属性
print(p[0]) #按照元组下标法访问也可以

 

(2) deque

比较方便的解决了频繁删除插入带来的效率问题

q=collections.deque(['a','b','c'])
print(q)
q.append("d")
print(q)
q.appendleft("x")
print(q)

(3) defaultdict

当直接读取dict不存在的属性时,直接返回默认值

func=lambda:"12345678"
d1=collections.defaultdict(func)
d1["A"]=1
d1["B"]=2
print(d1["C"])

(4) counter

统计字符串中每个字符出现的次数

也可以进行词频统计

co=collections.Counter("AADHHANANV")
print(co)#Counter({'A': 4, 'H': 2, 'N': 2, 'D': 1, 'V': 1})

 

lst=["love","hello","love","hello","stu","tea"]
sc=collections.Counter(lst)
print(sc) #Counter({'love': 2, 'hello': 2, 'stu': 1, 'tea': 1})

 

二、    调试技术

分类:静态调试:

      动态调试:

pdb调试

pycharm调试:run/debug模式

   断点:程序在debug模式下遇到断点就会暂停运行

 

三、    列表高级操作

  1. 切片
  2. 迭代
#切片:取一个列表或者元组的部分元素
lst=["LY","I","LOVE","YOU"]
#取第一个元素---索引法,下标法
print(lst[0])
#切片操作
lst3=lst[0:3] #取前三个元素
print(lst3)
#从开头开始取,冒号(:)前面的数字0可以省略
lst3=lst[:3]
print(lst3)
#取到最后的话,冒号(:)后面的数字可以省略
#从第二个元素(下标是1)取到最后
lst4=lst[1:]
print(lst4)
#负数表示从后往前取
lstf1=lst[-1] #表示取倒数第一个元素
print(lstf1) #YOU
#
每2个取一个,也就是取第1、3、5、7...个元素
lst2=lst[::2]
print(lst2)

如果给定一个list或tuple,我们可以通过while或for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)

3. 列表生成式

4. 生成器

#生成一个元素为1-10的列表
#法1;list函数
lst=list(range(1,11))
print(lst)
#法2:循环
lst=[i for i in range(1,11)]
print(lst)
#法3:循环2
lst=[]
for i in range(1,11):
    lst.append(i)
print(lst)
#拓展:迭代字典的key 和 value
d={"xiaoming":100,"xiaoli":98,"xiaohong":95}
for k,v in d.items():
    print(k,"的成绩是",v,"分")
#也可以用列表生成式实现上述功能
lst_dict=[k+"的成绩是"+str(v)+"分" for k,v in d.items()]
print(lst_dict)

在Python中,这种一边循环一边计算的机制,称为生成器:generator。

#generator
#
法1:将列表生成式的[]改为()
L=[x*x for x in range(10)]
print(L)#[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
g=(x*x for x in range(10))
print(g) #<generator object <genexpr> at 0x0000029937B04728>
#
打印出generator的每一个元素 --->next函数
print(next(g)) #0
print(next(g)) #1
print(next(g)) #4

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

当然,上面这种不断调用next(g)存在不合理的地方,正确的方法是使用for循环,因为generator也是可迭代对象

for n in g:

   print(n)

所以,我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:

               1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

def fib(max):
    n,a,b=0,0,1
    while n<max:
        print(b)
        a,b=b,a+b
        n=n+1
    return 'done'
print(fib(6))

可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。

要把fib函数变成generator,只需要把print(b)改为yield b就可以了。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

def fib(max):
    n,a,b=0,0,1
    while n<max:
        yield b
        a,b=b,a+b
        n=n+1
    return 'done'
print(fib(6)) #<generator object fib at 0x00000169FD5C47D8>
for i in fib(6):
    print(i,end=' ') #1 1 2 3 5 8

generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

5. 迭代器

可以直接作用于for循环的数据类型有以下几种:

  一类是集合数据类型,如list、tuple、dict、set、str等;

  一类是generator,包括生成器和带yield的generator function。

        这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

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

list、dict、str等数据类型不是Iterator。

posted @ 2020-03-23 20:42  程序员王不错  阅读(185)  评论(0)    收藏  举报