Python学习之路第二天——迭代器生成器算法基础

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习之路第二天——迭代器生成器算法基础相关的知识,希望对你有一定的参考价值。

一、迭代器:

迭代器是访问集合元素的一种方式。

迭代器对象是从集合的第一个元素开始访问,直到所有的元素被访问完结束。

迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。

另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存

1、创建一个迭代器:

技术分享
x = iter([1, 2, 3, 4])
print(x)

以上实例输出结果:
<list_iterator object at 0x000000000107C1D0>
迭代器(iter)

2、迭代器操作:

技术分享
__next__()函数:就是取迭代器内的值:
x = iter([1, 2, 3, 4])
print(x.__next__())
print(x.__next__())
print(x.__next__())
print(x.__next__())
print(x.__next__())
以上实例输出结果:
1
2
3
4
Traceback (most recent call last):
  File "E:/project/s12/day1/test.py", line 11, in <module>
    print(x.__next__())
StopIteration
注:当迭代器内的值全部取完后,就会报出如上错误。
取值(__next__())

二、生成器(yield):

定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器。

技术分享
def cash_out(amount):
    while amount >0:
        amount -= 1
        yield 1
        print("擦,又来取钱了。。。败家子!")
ATM = cash_out(3)
print("取到钱 %s 万" % ATM.__next__())
print("花掉花掉!")  
print("取到钱 %s 万" % ATM.__next__())
print("取到钱 %s 万" % ATM.__next__())

以上实例输出结果:
取到钱 1 万
花掉花掉!
擦,又来取钱了。。。败家子!
取到钱 1 万
擦,又来取钱了。。。败家子!
取到钱 1 万
注:yield函数可以使一个循环执行一半时做别的操作,然后再反回循环继续执行。
yield

作用:

yield的主要效果,就是可以使函数中断,并保存中断状态,中断后,代码可以去执行其他操作,其他操作完成后,还可以再重新调用这个函数,从上次yield的下一句开始执行。

 

3、yield接收参数:

yield实现在单线程的情况下实现并发运算的效果:

技术分享
import time
def consumer(name):
    print("%s 准备吃包子啦!" %name)
    while True:
       baozi = yield
       print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
def producer(name):
    c = consumer(A)
    c2 = consumer(B)
    c.__next__()
    c2.__next__()
    print("老子开始准备做包子啦!")
    for i in range(3):
        time.sleep(1)
        print("做了2个包子!")
        c.send(i)
        c2.send(i)
producer("Earl")

以上实例输出结果:
A 准备吃包子啦!
B 准备吃包子啦!
老子开始准备做包子啦!
做了2个包子!
包子[0]来了,被[A]吃了!
包子[0]来了,被[B]吃了!
做了2个包子!
包子[1]来了,被[A]吃了!
包子[1]来了,被[B]吃了!
做了2个包子!
包子[2]来了,被[A]吃了!
包子[2]来了,被[B]吃了!
send向yield传参数:

 

三、装饰器:

需求:当我们开发好了一个接口,这个接口是提供给用户使用,但是在使用过程中需要添加一下功能,在不改变接口调用方式与代码的情况下,增加这个功能,怎么办呢?这个时候就需要装饰器上场了。

技术分享
def login(func):
    def x (user):
        if user == earl:
            return func(user)
    return x
@login
def tv(name):
    print(欢迎%s,来到电视剧频道 %name)
tv(earl)

以上实例输出结果:
欢迎earl,来到电视剧频道
装饰器实例

装饰器传递参数实例:

技术分享
def Before(request):
    print(before)

def After(request):
    print(after)

def Filter(before_func,after_func):
    def outer(main_func):
        def wrapper(request):
            before_result = before_func(request)
            if(before_result != None):
                return before_result;
            main_result = main_func(request)
            if(main_result != None):
                return main_result;
            after_result = after_func(request)
            if(after_result != None):
                return after_result;
        return wrapper
    return outer

@Filter(Before, After)
def Index(request):
    print(index)

Index(example)


以上实例输出结果:
before
index
after
装饰器传递参数:

说明:一个函数如果在函数名加上括号例如func()是执行func这个函数,如果不加括号例如func说是取func这个函数的内存id值,不执行函数,在迭代器中很多return调用的是只是函数名。所以在使迭代器中对这个要多注意。

 

四、递归:

特点

递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

 

1、利用函数编写如下数列:

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368

技术分享
def func(arg1, arg2):
    if arg1 == 0:
        print(arg1, arg2)
    arg3 = arg1 + arg2
    if arg3 < 10:
        print(arg3)
        func(arg2, arg3)

func(0,1)

以上实例输出结果:
0 1
1
2
3
5
8
递归实例:

2、通过递归实现2分查找:

技术分享
def binary_search(data_list,find_num):
    mid_pos = int(len(data_list) /2 ) 
    mid_val = data_list[mid_pos] 
    print(data_list)
    if len(data_list) >= 1:
        if mid_val > find_num:
            print("[%s] should be in left of [%s]" %(find_num,mid_val))
            binary_search(data_list[:mid_pos],find_num)
        elif mid_val < find_num: 
            print("[%s] should be in right of [%s]" %(find_num,mid_val))
            binary_search(data_list[mid_pos:],find_num)
        else: 
            print("Find ", find_num)
    else:
        print("cannot find [%s] in data_list" %find_num)
if __name__ == __main__:
    primes = list(range(1,20))
    binary_search(primes,10)

    else:
        print("cannot find [%s] in data_list" %find_num)

if __name__ == __main__:
    primes = list(range(1,30))
    binary_search(primes,10)

以上实例输出结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
[10] should be in left of [15]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
[10] should be in right of [8]
[8, 9, 10, 11, 12, 13, 14]
[10] should be in left of [11]
[8, 9, 10]
[10] should be in right of [9]
[9, 10]
Find  10
2分查找实例:

五、基础算法:

生成一个4*4的2维数组并将其顺时针旋转90度

技术分享
array=[[col for col in range(5)] for row in range(5)] #初始化一个4*4数组
for row in array: #旋转前先看看数组长啥样
    print(row)

print(-------------)
for i,row in enumerate(array):

    for index in range(i,len(row)):
        tmp = array[index][i]
        array[index][i] = array[i][index]
        print(tmp,array[i][index])
        array[i][index] = tmp
    for r in array:print(r)

    print(--one big loop --)

以上实例输出结果:
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
-------------
0 0
0 1
0 2
0 3
0 4
[0, 0, 0, 0, 0]
[1, 1, 2, 3, 4]
[2, 1, 2, 3, 4]
[3, 1, 2, 3, 4]
[4, 1, 2, 3, 4]
--one big loop --
1 1
1 2
1 3
1 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 3, 4]
[3, 3, 2, 3, 4]
[4, 4, 2, 3, 4]
--one big loop --
2 2
2 3
2 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 2, 2]
[3, 3, 3, 3, 4]
[4, 4, 4, 3, 4]
--one big loop --
3 3
3 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 2, 2]
[3, 3, 3, 3, 3]
[4, 4, 4, 4, 4]
--one big loop --
4 4
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]
[2, 2, 2, 2, 2]
[3, 3, 3, 3, 3]
[4, 4, 4, 4, 4]
--one big loop --
4*4的2维数组实例:

 

以上是关于Python学习之路第二天——迭代器生成器算法基础的主要内容,如果未能解决你的问题,请参考以下文章

Python菜鸟之路:Python基础-生成器和迭代器

Python高手之路python基础之迭代器与生成器

python---学习之路

python 学习第四天

python之路

Python学习之路8?迭代器协议和生成器