一、迭代器

1.Iterable(可迭代的)

我们已经知道可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型:list tuple dict set str 等

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

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

可以使用isinstance()判断一个对象是否是Iterable对象

form collections import Iterable

isinstance([ ],Iterable)

true

 

2.Iterator(迭代器)

而生成器不但可以作用于for循环还可以被next()函数不断调回并返回下一个值 直到最后抛出 stopIteration 错误表示无法继续返回下一个值了

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

同样可以使用isinstance()判断一个对象是否是Iterator对象

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

Python的for循环本质上就是通过不断调用next()函数实现的,例如:

for x in [1, 2, 3, 4, 5]:
    pass
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
    try:
        # 获得下一个值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循环
        break

 

二、生成器

参考:https://blog.csdn.net/weixin_37720172/article/details/78482291

假设某列表元素过于庞大 而且可以通过固定的算法实现 这种一边循环一边计算的机制 被称为 生成器 generator

我们可以用列表生成式来生成一个列表

l=[x for x in range(5)] 
print (l)

[0, 1, 2, 3, 4]

我们可以用类似的方式生成一个生成器

g=(x for x in range(5))
print g

<generator object <genexpr> at 0x000000000396D360>

可以看到它返回一个生成器

那么怎么返回这个生成器的值呢? 有两种方法

>>> for m in g:print m
...
0
1
2
3
4

>>> g=(x for x in range(5))
>>> next(g)
0
>>> next(g)
1
>>> next(g)
2
>>> next(g)
3
>>> next(g)
4
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

生成器在面对庞大的列表时 会大量的节省内存空间 下面这段代码就可以验证一波

import time

def get_time(func):
    def wraper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print("Spend:", end_time - start_time)
        return result
    return wraper

@get_time
def _list(n):
    l1 = [list(range(n)) for i in range(n)]
    del l1


@get_time
def _generator(n):
    ge = (tuple(range(n)) for i in range(n))
    del ge

_list(1000)
_generator(1000)

 

('Spend:', 0.026999950408935547)
('Spend:', 0.0)

 

生成器中yield的使用:

yield就是专门给生成器用的return yield的作用在于保存一个generator的状态

还可通过yield实现在单线程情况下实现并发运算的效果

import time
def consumer(name):
    print '%s开始' %name
    while True:
        baozi = yield
        print '%s来了%s吃了' %(baozi,name)
def producter(name):
    c=consumer('A')
    c1=consumer('B')
    c.next()
    c1.next()
    print 'begin!'
    for i in range(10):
        time.sleep(1)
        c.send(i)
        c1.send(i)
producter('C')
yield实现异步

一个函数中含有yield的话 默认调用这个函数的为生成器

yield 可以通过send接收数据

三、装饰器

对已有功能的扩展 不改变源代码 

@函数名 称为语法糖  程序执行到语法糖后 会执行此函数 并且以该语法糖下面的函数作为 参数

@函数名 该语法糖中的函数 至少有两层 第一层接收函数 第二层接收 语法糖下面函数所传的参数

注:被装饰的函数所携带的参数

#一个参数
def w1(func):
    def inner(arg):
        # 验证1
        # 验证2
        # 验证3
        return func(arg)
    return inner

@w1
def f1(arg):
    print 'f1'

#二个参数
def w1(func):
    def inner(arg1,arg2):
        # 验证1
        # 验证2
        # 验证3
        return func(arg1,arg2)
    return inner

@w1
def f1(arg1,arg2):
    print 'f1'

#n个参数
def w1(func):
    def inner(*args,**kwargs):
        # 验证1
        # 验证2
        # 验证3
        return func(*args,**kwargs)
    return inner
 
@w1
def f1(arg1,arg2,arg3):
    print 'f1'

#
参数

一个函数被多个装饰器装饰

def w1(func):
    def inner(*args,**kwargs):
        # 验证1
        # 验证2
        # 验证3
        return func(*args,**kwargs)
    return inner
 
def w2(func):
    def inner(*args,**kwargs):
        # 验证1
        # 验证2
        # 验证3
        return func(*args,**kwargs)
    return inner
 
 
@w1
@w2
def f1(arg1,arg2,arg3):
    print 'f1'

 

四、递归

函数执行过程中调用函数本身

 注:递归要有一个明确的出口

递归算法的效率较低 每次递归都要在内存中保存一次函数体

五、简单算法

1、二分查找

def binary_search(data_source,find_s):
    print data_source
    mid=len(data_source)/2
    if len(data_source) >= 1:
        if data_source[mid] > find_s:
            print '%s is in %s left' %(find_s,data_source[mid])
            binary_search(data_source[:mid],find_s)
        elif data_source[mid] < find_s:
            print '%s is in %s right' % (find_s, data_source[mid])
            binary_search(data_source[mid:], find_s)
        else:
           print  'find %s' %data_source[mid]
    else:
        print 'cant find'


if __name__ == '__main__':
    data=list(range(1,600,3))
    binary_search(data,1)
二分法递归查找

2、二维列表90度旋转

# a=[i for i in range(4)]
# print a
a=[[i for i in range(4)]for j in range(4)]
# print a
#for b in a:print b
for b_index,b in enumerate(a):
    #print b,b_index
    for l in range(b_index,len(b)):
        tmp=a[b_index][l]
        a[b_index][l]=a[l][b_index]
        a[l][b_index]=tmp
        for c in a :print c
        print '------'
列表顺时针选装90度

涉及到列表的下标  可以使用range(len(列表名))

六、python正则

字符:

 

  . 匹配除换行符以外的任意字符
  \w 匹配字母或数字或下划线或汉字
  \s 匹配任意的空白符
  \d 匹配数字
  \b 匹配单词的开始或结束
  ^ 匹配字符串的开始
  $ 匹配字符串的结束

 

次数:

 

  * 重复零次或更多次
  + 重复一次或更多次
  ? 重复零次或一次
  {n} 重复n次
  {n,} 重复n次或更多次
  {n,m} 重复n到m次

re.search    search,浏览整个字符串去匹配第一个,未匹配成功返回None

re.findall      findall,获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖; 空的匹配也会包含在结果中

re.match match  从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None

 

七、python实现简单计算器

#-*- coding:utf-8-*-
import re
def fg(sz):

    sz2=[ ]
    sz3=[ ]

    for sz_index,i in enumerate(sz1):
        if i=='(':
            ks=sz_index+1
        elif i==')':
            js=sz_index
            for j in range(ks,js):
                sz2.append(sz1[j])
                if j == js-1:
                    cc(sz2)
                    for d in range(ks - 1, js + 1):
                        sz1.pop(ks-1)
                    for x in sz2:
                        sz1.insert(ks-1,x)
                    fg(sz1)
                    cc(sz1)
                    sz3=jj(sz1)
                    return sz3[0]
def jj(sz3):
    for p_index,p in enumerate(sz3):
        if p == '+':
            n1=int(sz3[p_index-1])
            n2=int(sz3[p_index+1])
            n=n1 + n2
            #print n
            n = str(n)
            sz3.insert(p_index-1,n)
            sz3.pop(p_index)
            sz3.pop(p_index)
            sz3.pop(p_index)
            #print sz3
            jj(sz3)
        if p == '-':
            n1=int(sz3[p_index-1])
            n2=int(sz3[p_index+1])
            n=n1 - n2
            n = str(n)
            sz3.insert(p_index-1,n)
            sz3.pop(p_index)
            sz3.pop(p_index)
            sz3.pop(p_index)
            jj(sz3)
    #print sz3
    return sz3

def cc(sz2):
    for l_index,l in enumerate(sz2):
        if l == '*' :
            m1=int(sz2[l_index-1])
            m2=int(sz2[l_index+1])
            m=m1 * m2
            m = str(m)
            sz2.insert(l_index-1, m)
            sz2.pop(l_index)
            sz2.pop(l_index)
            sz2.pop(l_index)
            cc(sz2)
        elif l == '/':
            m1 = int(sz2[l_index - 1])
            m2 = int(sz2[l_index + 1])
            m = m1 / m2
            m=str(m)
            sz2.insert(l_index - 1, m)
            sz2.pop(l_index)
            sz2.pop(l_index)
            sz2.pop(l_index)
            cc(sz2)
    #print sz2
    return sz2

if __name__== '__main__':
    ss=raw_input('请输入:')
    sz1 = re.findall('[0-9]+|\*|\/|\+|\-|\(|\)',ss)
    print fg(ss)
计算器 带括号

 

posted on 2018-09-10 14:46  大侠之运维  阅读(183)  评论(0编辑  收藏  举报