python3.6-冒泡排序,迭代器和生成器

冒泡排序:

算法描述:
(1)外层循环 len(nums)-1 次,内层循环 len(nums)-i-1 次
(2)每次循环中,如果 前面的数大于后面的数,就交换
(3)设置一个标签,如果上次没有交换,就说明这个是已经好了的。

nums = [55,6,17,36,20,67,88]
for i in range(len(nums)-1):
    for j in range(len(nums)-i-1):
        if nums[i] > nums[i+1]:
            nums[i],nums[i+1] = nums[i+1],nums[i]
print(nums)

函数方法写: 

li = [55,6,17,36,20,67,88]
def bubble(li):
    flag = True
    for i in range(len(li)-1):
        if flag:
            for j in range(i):
                if li[j] > li[j+1]:
                    li[j],li[j+1] = li[j+1],li[j]
    print(li)
bubble(li)


迭代器:

迭代器是Python中最强大的功能之一,是访问集合元素的一种方式,包括:list.tuple.dict.str对象都可以用于创建迭代器;

迭代器是一个可以记住遍历的位置的对象;

迭代器从集合的第一个元素开始访问,一直到所有元素都被访问完结束,迭代器只向前走,不向后退;

迭代器的2个基本方法:  __iter()__  和 __next()__

__iter()__方法:返回迭代器自身,return self,可以通过python的内建函数iter()调用

__next()__方法:当__next()__方法被调用的时候,迭代器会返回它的下一个值,如果到最后没有可返回的值了,就会引发一个StopIteration异常,该方法可以通过 python 内建函数next()调用。



创建迭代器的3种方法:

方法一:

容器对象添加 __iter__()__next__() 方法(Python 2.7 中是 next());__iter__() 返回迭代器对象本身 self,__next__() 则返回每次调用 next() 或迭代时的元素;


自定义一个迭代器:

class Contain:
    def __init__(self,start,end):
        self.start = start          #self.start既是开始位置,也是记录位置的状态
        self.end = end
    def __iter__(self):
        print('调用iter方法!')
        return self     #/__iter()__返回自身self
    def __next__(self):
        if self.start < self.end:
            i = self.start
            self.start += 1
            return i
        else:
            raise StopIteration
Con = Contain(0,5)
for i in Con:
    print(i)

方法二:使用内建函数iter()可以从可迭代对象中获得迭代器

li = [2,5,3,7,9,10]
it = iter(li)
print(next(it), end=' ')    #2
print(next(it), end=' ')    #5以此类推

方法三:

利用生成器(generator),生成器通过yield语句快速生成迭代器,省略了复杂的__iter()__和__next()__方式

1.生成器: generator 第一种创建方式(推导式):

nums = (x for x in range(10))
print(nums)              #<generator object <genexpr> at 0x0000004590AB9938>  生成器类型
for i in nums:
    print(i, end=' ')    #0 1 2 3 4 5 6 7 8 9 

nums = (x for x in range(2))
print(nums)
print(next(nums))   #0
print(next(nums))   #1
print(next(nums))   #报错 StopIteration

2.第二种创建方式(斐波那契数列):

fibs = []
for i in range(20):
    if i > 1:
        fibs.append(fibs[i-2]+fibs[i-1])
    else:
        fibs.append(1)
    print(fibs[i],end=' ')     #1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 
转换成yield:  必须要在def中

fibs = []
def Fib():
    for i in range(20):
        if i > 1:
            fibs.append(fibs[i-2]+fibs[i-1])
        else:
            fibs.append(1)
        yield fibs[i]     #print换成yield ,每次生成一个值
fibnaqi = Fib()
print(fibnaqi.__next__())   #1
print(next(fibnaqi))        #1
print(next(fibnaqi))        #2
在方法内使用yield做生成器,这样调用此方法时,会得出一个结果:generator object...
然后也是可以调用next()
每到yield时,就会停止,返回当前这个值,可以一次一次next()调用,看看运行过程
生成器可以被循环迭代,直到循环结束

import collections
print(isinstance([], collections.Iterable))            # True
print(isinstance(iter([]), collections.Iterator))      # True
print(isinstance(iter([]), collections.Iterable))      # True
print(isinstance([], collections.Iterator))            # False
print(isinstance((x * x for x in range(10)), collections.Iterable))    #推导是可迭代元素,但不是迭代器


练习:将一个普通循环转换为一个生成器,调用__next__不会输出结果
xxx.send()方法可以给yield传值,但先使用了next()才可使用,或者传一个None,send(None)
yield可以模拟多任务执行

def Function():
    for i in range(20):
        yield i
fun = Function()

print(next(fun))
print(next(fun))
print(next(fun))

def Function(x):
    for i in range(x):
        yield i
fun1 = Function(3)
fun2 = Function(5)
print(next(fun1))
print(next(fun1))
print(next(fun1))

print(next(fun2))
print(next(fun2))
print(next(fun2))




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值