Py Tips

作为 pprint 模块的替代方案(json.dumps)

# `dict` 的标准字符串 `repr` 很难阅读:
>>> my_mapping = {'a': 23, 'b': 42, 'c': 0xc0ffee}
>>> my_mapping
{'b': 42, 'c': 12648430. 'a': 23}  # 

# `json` 模块可以做的更好  indent 表示空几个空格、sort_keys 表示排序 key
>>> import json
>>> print(json.dumps(my_mapping, indent=4, sort_keys=True))
{
    "a": 23,
    "b": 42,
    "c": 12648430
}

如何合并俩个字典

>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 3, 'c': 4}
>>> z = {**x, **y}
>>> z
{'c': 4, 'a': 1, 'b': 3}  # 在 Python 2.x ,你可以这样做
>>> z = dict(x, **y)
>>> z
{'a': 1, 'c': 4, 'b': 3}

is VS ==

>>> a = [1, 2, 3]
>>> b = a

>>> a is b
True
>>> a == b
True

>>> c = list(a)

>>> a == c
True
>>> a is c
False

# is  如果俩个变量点指向统一对象则为真
# == 如果俩个变量值相等则为真

如何根据值对 dict 进行排序

>>> xs = {'a': 4, 'b': 3, 'c': 2, 'd': 1}

>>> sorted(xs.items(), key=lambda x: x[1])
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]

# Or:

>>> import operator
>>> sorted(xs.items(), key=operator.itemgetter(1))
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]

命名元组

# 手动定义类
>>> from collections import namedtuple
>>> Car = namedtuple('Car', 'color mileage')

>>> my_car = Car('red', 3812.4)
>>> my_car.color
'red'
>>> my_car.mileage
3812.4

>>> my_car
Car(color='red' , mileage=3812.4)

# 像元组一样,命名元组是不可变的
>>> my_car.color = 'blue'
AttributeError: "can't set attribute"

变量交换

a = 23
b = 42

# python 可以这样做,变量交换
a, b = b, a

迭代多个序列


a = [1, 2, 3]
b = [4, 5, 6]

for item in a:
    ...

for item in b:
    ...

# python 可以这样做
from itertools import chain  # chain 里面可以放置多个序列
for item in chain(a, b):
    print(item)

Python的切片

在列表操作中,支持索引操作,使用[ 索引 ]取出对应索引的值,Python支持正向索引,也支持负向索引。

alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
#            0    1    2    3    4    5    6    7    8    9
#           -10  -9   -8   -7   -6   -5   -4   -3   -2   -1

print(alphabet[4])      # e 
print(alphabet[-6])     # e

Python中所有的有序序列都支持索引和切片,有序序列如:字符串,元组,列表。

切片返回的结果和切片的类型一致,返回的切片对象是切片对象的子序列。如:对一个列表切片返回一个列表,对字符串进行切片返回一个字符串。
而且切片是一种浅拷贝。

li = [‘A’,’B’,’C’,’D’]
切片的格式: li[ start : end :step]
start是切片起点索引,end是切片终点索引,但切片结果不包括终点索引的值。step是步长默认是1。

alphabet = ["a", "b", "c", "d"]
#            0    1    2    3
#           -4   -3   -2   -1

print(alphabet[0:3])        # ['a', 'b', 'c']  起点的0可以生省略 相当于alphabet[:3]
print(alphabet[2:])         # ['c', 'd']    省略end切到最后
print(alphabet[1:3])        # ['b', 'c']
print(alphabet[0:4:2])      # ['a', 'c']    从0到3,步长为2

在step的符号一定的情况下,start和end可以混合使用正向和反向索引。如何确定start和end,他们之间什么关系?

无论怎样,你都要保证start和end之间有元素间隔,并且和step方向一致,否则会切出空列表。

step为正,方向为左到右

alphabet = ["a", "b", "c", "d"]
#            0    1    2    3
#           -4   -3   -2   -1

print(alphabet[0:2])
print(alphabet[0:-2])
print(alphabet[-4:-2])
print(alphabet[-4:2])

# 都是['a', 'b']

step为负,方向为右到左

alphabet = ["a", "b", "c", "d"]
#            0    1    2    3
#           -4   -3   -2   -1

print(alphabet[-1:-3:-1])
print(alphabet[-1:1:-1])
print(alphabet[3:1:-1])
print(alphabet[3:-3:-1])

# 都是['d', 'c']

step默认为正,方向为左到右,同时,step的正负决定了切片结果的元素采集的先后

alphabet = ["a", "b", "c", "d"]
#            0    1    2    3
#           -4   -3   -2   -1

print(alphabet[-1:-3])
print(alphabet[-1:1])
print(alphabet[3:1])
print(alphabet[3:-3])

# 以上都是空列表

省略start和end,全切

alphabet = ["a", "b", "c", "d"]
#            0    1    2    3
#           -4   -3   -2   -1

print(alphabet[:])              # ['a', 'b', 'c', 'd']
print(alphabet[::-1])           # ['d', 'c', 'b', 'a']
#!/usr/bin/env python
# -*- coding: utf-8 -*-
lst = ['','周星星','麻花藤','周扒皮']

for i in range(len(lst)-1,-1,-1):
    print(i,range(len(lst)-1,-1,-1))
    if lst[i][0] =='':
        lst.pop(i)
print(lst)
'''
3 range(3, -1, -1)
2 range(2, -1, -1)
1 range(2, -1, -1)
0 range(1, -1, -1)
['麻花藤']
'''

lst = ['','周星星','麻花藤','周扒皮']
lst1=[]
for i in lst:
    if i.startswith(''):
        lst1.append(i)
for j in lst1:
        lst.remove(j)
print(lst) #['麻花藤']


# 补充:方式3
li = ['','周星星','麻花藤','周扒皮']
print(list(filter(lambda x:x[0]!='',li)))
列表
#! /user/bin/env python
# -*- coding: utf-8 -*-
def fib(max):
    n,a,b = 0,0,1
    while n < max:
        yield  b
        a,b = b,a+b
        n += 1
    return 'haha'


print(fib(6).__next__(),id(fib(6).__next__()))  #操作fib(6)这个生成器
print(fib(6).__next__(),id(fib(6).__next__()))  #操作又一个fib(6)这个生成器
print(fib(6).__next__(),id(fib(6).__next__()))  #操作又一个新生成的fib(6)这个生成器
#函数名()的到的结果就是生成器,上面始终在操作新的生成器

pro=fib(6)  #生成一个生成器
print(pro.__next__(),id(pro.__next__()))  #操作这个已经生成的生成器pro
print(pro.__next__(),id(pro.__next__()))  #操作这个已经生成的生成器pro
print(pro.__next__(),id(pro.__next__()))  #操作这个已经生成的生成器pro
#函数名()的到的结果就是生成器,上面操作的一直是Pro这一个生成器

#你从__next__()的id就能看出,fib(6)是新生成的生成器。
生成器
#! /user/bin/env python
# -*- coding:utf-8 -*-

# 运行代码的时候把其他重名函数注释了看效果。

def fun():
    temp=[lambda x:x*i for i in range(4)]
    return temp
for every in fun():
    print(every(2))

#上面的代码可以写成这样,这样你就能看的更清楚一些
def func():
    temp = []
    for i in range(4):
        def foo(x):
            # print(i)
            # 这可以打印了看看i的值,已经是3了,函数foo中没有变量i,按照函数作用域的查找顺序就向外找
            # 外部函数func中寻找变量 i ,但此时外部的 for 已经循环完毕,最后的 i =3
            # 所以,每次执行every(2),i 的值都是 3 ,因此,最终结果会是 [6, 6, 6, 6] 。
            return x*i
        temp.append(foo)
    return temp
for every in func():
    print(every(2))


# #补充:如果你想运用每次循环中i的值,就把i当参数传进去
def func():
    temp = []
    for i in range(4):
        def foo(x,i=i):
            # 为什么这不写成foo(x,i)?
            # 原因1:你看看every(2)的调用方式是不是只有一个参数,说明i这个参数要有默认值
            # 原因2:又想把每次循环中的i传进去就可以这样写 i=i
            return x*i
        temp.append(foo)
    return temp
for every in func():
    print(every(2))

# #补充: 如果上面的代码发懵的话,改一下形参的名称如下和上面是一样的效果:
def func():
    temp = []
    for i in range(4):
        def foo(x,y=i):
            return x*y
        temp.append(foo)
    return temp
for every in func():
    print(every(2))


#补充用匿名函数写的话就是这样: 第二个形参名称为y
def fun():
    temp=[lambda x,y=i:x*y for i in range(4)]
    return temp
for every in fun():
    print(every(2))

#补充用匿名函数写的话就是这样: 第二个形参名称为i
def fun():
    temp=[lambda x,i=i:x*i for i in range(4)]
    return temp
for every in fun():
    print(every(2))
函数
#! /user/bin/env python
# -*- coding:utf-8 -*-
# def outer():
#     n = 5
#     def inner():
#         nonlocal n
#         n = n + 1
#         print(n)
#     # print(n)
#     return inner
# f = outer()
# f()
# f()


#首先看明白下面这段代码:
gcount = 0
def global_test():
    global gcount
    gcount += 1  # 这里是+= 已经对gcount 重新赋值了
    print(gcount)
global_test() #打印1
global_test() #打印2
global_test() #打印3
print(gcount) #打印3

#global关键字用来在函数或其他局部作用域中使用全局变量。
#上面的代码应该看的懂,那你就只需要知道nonlocal的作业是什么。举一反三就出来了,是一样的原理。
#nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。
nonlocal
"""
1. 把有依赖关系的类放到容器中,解析出这些类的实例,就是依赖注入。目的是实现类的解耦。

2. 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

3. Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。

"""
class Mapper:
    # 在字典里定义依赖注入关系
    __mapper_relation = {}

    # 类直接调用注册关系
    @staticmethod
    def register(cls, value):
        Mapper.__mapper_relation[cls] = value

    @staticmethod
    def exist(cls):
        if cls in Mapper.__mapper_relation:
            return True
        return False

    @staticmethod
    def get_value(cls):
        return Mapper.__mapper_relation[cls]


class MyType(type):
    def __call__(cls, *args, **kwargs):
        obj = cls.__new__(cls, *args, **kwargs)
        arg_list = list(args)
        if Mapper.exist(cls):
            value = Mapper.get_value(cls)
            arg_list.append(value)
        obj.__init__(*arg_list, **kwargs)
        return obj

class Head:
    def __init__(self):
        self.name = 'alex'

class Foo(metaclass=MyType):
    def __init__(self, h):
        self.h = h
    def f1(self):
        print(self.h)

class Bar(metaclass=MyType):
    def __init__(self, f):
        self.f = f
    def f2(self):
        print(self.f)

Mapper.register(Foo, Head())
Mapper.register(Bar, Foo())

b = Bar()
print(b.f,type(b.f))
#<__main__.Foo object at 0x00000000043C5390> <class '__main__.Foo'>

f = Foo()
print(f.h,type(f.h))
#<__main__.Head object at 0x00000000041C6240> <class '__main__.Head'>
依赖注入
def home(request,site):
    blog = models.Blog.objects.filter(site=site).first()
    if not blog:
        return redirect('/')

    # 当前博客所有文章
    # models.Article.objects.filter(blog=blog)

    # 当前博客所有分类
    # 方式1:
    # cate_list = models.Category.objects.filter(blog=blog)
    # for item in cate_list:
    #     c = item.article_set.all().count()
    #     print(item,c)
    
    # 方式2:
    # from django.db.models import Count
    # category_list = models.Article.objects.filter(blog=blog).values('category_id','category__title',).annotate(c=Count('nid'))
    
    # SQL语句:    
    # select category_id,category__title,count(nid) as c from article where blog_id=1 group by category_id and category__title

    # 获取博客标签
    # 方式1:
    # tag_list = models.Tag.objects.filter(blog=blog)
    # for tag in tag_list:
    #     c = tag.article_set.all().count()
    #     print(tag,c)
    
    # 方式2:
    from django.db.models import Count
    # models.Article2Tag.objects.filter(tag__blog=blog).values('tag_id','tag__title').annotate(c=Count('id'))


    # 自己没有创建Article2Tag表时:
    # v1 = models.Article.objects.filter(blog=blog).values('nid','title')
    # print(v1.query) 查看SQL语句
    # v2 = models.Article.objects.filter(blog=blog).values('tags__id','tags__title').annotate(c=Count('nid'))


    # 时间分类:
    # models.Article.objects.filter(blog=blog).values('create_time').annotate(c=Count('nid'))
    # select createtime,count(nid) as c from article where blog_id=1 group by create_time

    # select date_format(create_time,'%Y-%m'),count(nid) as c from article where blog_id=1 group by date_format(create_time,'%Y-%m')
    # 2015-09  10
    # 2015-10  8

    # MySQL
    # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "date_format(create_time,'%%Y-%%m')"}).values('c').annotate(ct=Count('nid'))
    # SQLlite
    # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "strftime('%%Y-%%m',create_time)"}).values('c').annotate(ct=Count('nid'))

    """
    nid xx   create_time            c
     1  x     2018-01-01 11:11    2018-01

    """
    # 小结:
    """
    1. 分类
        category_list = models.Article.objects.filter(blog=blog).values('category_id','category__title',).annotate(c=Count('nid'))
    2. 标签
        tag_list = models.Article2Tag.objects.filter(tag__blog=blog).values('tag_id','tag__title').annotate(c=Count('id'))
    3. 时间
        # MySQL
        # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "date_format(create_time,'%%Y-%%m')"}).values('c').annotate(ct=Count('nid'))
        # SQLlite
        # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "strftime('%%Y-%%m',create_time)"}).values('c').annotate(ct=Count('nid'))

    """
    #django中的列不能是其他,只能是已经存在的列名,下面的写法不对:
    date_list = models.Article.objects.filter(blog=blog).values("date_format(create_time,'%%Y-%%m')").annotate(ct=Count('nid'))

    # 了解ORM内置基础函数:
    from django.db.models import functions
    # models.Article.objects.filter(blog=blog).annotate(x=functions.Extract('create_time','YEAR_MONTH'))
    # models.Article.objects.filter(blog=blog).annotate(x=functions.ExtractYear('create_time'))
    """
    nid xx   create_time            x
     1  x     2018-09-01 11:11      201809


    """
    # models.Article.objects.filter(blog=blog).annotate(x=functions.TruncMonth('create_time'))
    # models.Article.objects.filter(blog=blog).annotate(x=functions.Trunc('create_time',''))
    """
    nid xx   create_time            x
     1  x     2018-09-01 11:11      09


    """
    # from django.db.models import FloatField
    # from django.db.models import Value
    # v = models.Article.objects.annotate(c=functions.Cast('nid', FloatField()))
    # v = models.Article.objects.annotate(c=functions.Coalesce('title','summary'))
    # v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary'))
    # v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary',Value('666')))
    # v = models.Article.objects.annotate(c=functions.Greatest('nid','num'))
    # v = models.Article.objects.annotate(c=functions.Length('title'))
    # v = models.Article.objects.annotate(c=functions.Substr('title',1,1))
    #
    # """
    # select *,upper(title) from xxx
    # nid title summary   create_time      num        c
    #  1   xx        s   2018-09-01 11:11    9        x
    # """

    from django.db.models.functions.base import Func
    class YearMonthFunc(Func):
        function = 'DATE_FORMAT'
        template = '%(function)s(%(expressions)s,%(format)s)'

        def __init__(self, expression, **extra):
            expressions = [expression]
            super(YearMonthFunc, self).__init__(*expressions, **extra)

    v = models.UserInfo.objects.annotate(c=YearMonthFunc('create_time',format="'%%Y-%%m'"))

    """
    大结:
        1. 项目需求
            一对多,分组
            多对多,分组
            单表函数格式化,分组

            示例:
                1. 分类
                    category_list = models.Article.objects.filter(blog=blog).values('category_id','category__title',).annotate(c=Count('nid'))
                2. 标签
                    tag_list = models.Article2Tag.objects.filter(tag__blog=blog).values('tag_id','tag__title').annotate(c=Count('id'))
                3. 时间
                    # MySQL
                    # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "date_format(create_time,'%%Y-%%m')"}).values('c').annotate(ct=Count('nid'))
                    # SQLlite
                    # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "strftime('%%Y-%%m',create_time)"}).values('c').annotate(ct=Count('nid'))
        2. Django ORM内置函数,额外再取一列数据
            函数:
                - 基础
                    Cast, Coalesce, Concat, ConcatPair, Greatest, Least, Length, Lower, Now, Substr, Upper,
                - 时间
                    Extract, ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,ExtractSecond, ExtractWeekDay, ExtractYear, Trunc, TruncDate, TruncDay,TruncHour, TruncMinute, TruncMonth, TruncSecond, TruncYear,
            # from django.db.models import FloatField
            # from django.db.models import Value
            # v = models.Article.objects.annotate(c=functions.Cast('nid', FloatField()))
            # v = models.Article.objects.annotate(c=functions.Coalesce('title','summary'))
            # v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary'))
            # v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary',Value('666')))
            # v = models.Article.objects.annotate(c=functions.Greatest('nid','num'))
            # v = models.Article.objects.annotate(c=functions.Length('title'))
            # v = models.Article.objects.annotate(c=functions.Substr('title',1,1))
        3. 自定义
            from django.db.models.functions.base import Func
            class YearMonthFunc(Func):
                function = 'DATE_FORMAT'
                template = '%(function)s(%(expressions)s,%(format)s)'

                def __init__(self, expression, **extra):
                    expressions = [expression]
                    super(YearMonthFunc, self).__init__(*expressions, **extra)

            v = models.UserInfo.objects.annotate(c=YearMonthFunc('create_time',format="'%%Y-%%m'"))

    """

    return HttpResponse('...')
blog
x=[1,2,3]
y=[4,5,6]
zipped=list(zip(x,y))
print(zipped)  #[(1, 4), (2, 5), (3, 6)]
x2,y2=zip(*zipped)
print(x2,y2) #(1, 2, 3) (4, 5, 6)



x=[1,2,3]
y=[4,5,6]
z=[7,8,9]
n=list(zip(x,y,z))
print(n)  # [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

m=list(zip(*n))
print(m) #[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
zip
"""
如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做?
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
你说,so easy!
l.index(66)...
之所以用index方法可以找到,是因为python帮我们实现了查找方法。如果,index方法不给你用了。。。你还能找到这个66么?
"""

"""
这个方法就实现了从一个列表中找到66所在的位置了。
但我们现在是怎么找到这个数的呀?是不是循环这个列表,一个一个的找的呀?
假如这个列表特别长,里面好好几十万个数,那找一个数如果运气不好的话是不是要对比十几万次?这样效率太低了,得想一个新办法。

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]

i = 0
for num in l:
    if num == 66:
        print(i)
    i+=1
"""

#二分查找算法

"""
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
观察这个列表,这是不是一个从小到大排序的 有序 列表呀?
如果这样,假如要找的数比列表中间的数还大,是不是直接在列表的后半边找就行了?
"""
#简单版二分法
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
def find(l, num):
    if l:
        mid = len(l)//2
        if l[mid] > num:
            # 从左边找
            find(l[:mid], num)
        elif l[mid] < num:
            # 从右边找
            find(l[mid+1:], num)
        else:
            print('找到啦')
    else:
        print('找不到')

find(l,66)

#升级版二分法
def find2(l, num, start=0, end=None):
    end = end if end else len(l) - 1
    mid = (end-start)//2 + start
    if start >= end:
        print('找不到')
    elif l[mid] > num:
        find2(l, num, end=mid)
    elif l[mid] < num:
        find2(l, num, start=mid+1, end=end)
    else:
        print('找到啦', mid)

find2(l,66)  #找到啦 17
二分法
class S():
    def __init__(self, li):
        self.li = li

    def __iter__(self):
        return iter(self.li)

li=[S([11, 22, 33]),S(['a','b','c'])]
for row in li:
    for item in row:
        print(item)  #11,22,33,a,b,c


class S():
    def __init__(self, li):
        self.li = li

    def __iter__(self):
        yield 1
        yield 2

li = [S([11, 22, 33]), S(['a', 'b', 'c'])]
for row in li:
    for item in row:
        print(item)  # 1,2,1,2


class S():
    def __init__(self, li):
        self.li = li

    def __iter__(self):
        for item in self.li:
            yield item


li = [S([11, 22, 33]), S(['a', 'b', 'c'])]
for row in li:
    for item in row:
        print(item)  #11,22,33,a,b,c

"""
一个类中定义了__iter__方法且该方法返回一个迭代器,那么就称该类实例化的对象为可迭代对象(对象可以被循环)
生成器是一种特殊的迭代器
循环一个对象,就是执行其类中的__iter__方法。
"""



li = [S([11, 22, 33]), S(['a', 'b', 'c'])]
for row in li:
    for item in row:
        print(item)  #11,22,33,a,b,c


class S():
    def __init__(self, li):
        self.li = li

    def __iter__(self):
        for item in self.li:
            yield item*2

li = [S([11, 22, 33]), S(['a', 'b', 'c'])]
for row in li:
    for item in row:
        print(item)  #22,44,66,aa,bb,cc
类的__iter__
"""
生成器的问题
    取一次就没有了
    惰性运算,不取不执行
    取值方式:for  next  list
"""
ret=filter(lambda n:n%3==0,range(10))
print(len(list(ret))) #4
print(len(list(ret))) #0 之前list已经取没了


#########################

def demo():
    for i in range(4):
        yield i

g=demo()

g1=(i for i in g)
g2=(i for i in g1)

print(list(g1)) #[0, 1, 2, 3]  直接看从那开始取值的
print(list(g2)) #[]

#########################

def demo():
    for i in range(4):
        yield i

g=demo()

g1=(i for i in g)
g2=(i for i in g1)
print(list(g)) #[0, 1, 2, 3]  直接看从那开始取值的
print(list(g1)) #[]
print(list(g2)) #[]

#########################

def add(n,i):
    return n+i

def test():
    for i in range(4):
        yield i

g=test()
for n in [1,10]:
    g=(add(n,i) for i in g)

print(list(g)) #[20, 21, 22, 23]

"""
分解循环
for n in [1,10]:
    g=(add(n,i) for i in g)
    
1.循环中有生成器的先把循环拆解
n = 1 
g=(add(n,i) for i in g)
g=(add(n,i) for i in test())

n=10
g=(add(n,i) for i in g)
g=(add(n,i) for i in (add(n,i) for i in test()))
g=(add(10,i) for i in (add(10,i) for i in test()))
g=(add(10,i) for i in (add(10,i) for i in [0,1,2,3]))
g=(add(10,i) for i in (10,11,12,13))
g=(20,21,22,23)

    
"""

#########################

def add(n,i):
    return n+i

def test():
    for i in range(4):
        yield i

g=test()

for n in [1,10,5]:
    g=(add(n,i) for i in g)

print(list(g)) #[15, 16, 17, 18]


"""
分解循环
for n in [1,10]:
    g=(add(n,i) for i in g)

1.循环中有生成器的先把循环拆解
n = 1 
g=(add(n,i) for i in g)
g=(add(n,i) for i in test())

n = 10 
g=(add(n,i) for i in g)
g=(add(n,i) for i in (add(n,i) for i in test()))

n=5
g=(add(n,i) for i in (add(n,i) for i in (add(n,i) for i in test())))
g=(add(5,i) for i in (add(5,i) for i in (add(5,i) for i in [0,1,2,3])))
g=(add(5,i) for i in (add(5,i) for i in (5,6,7,8)))
g=(add(5,i) for i in (10,11,12,13))
g=(15,16,17,18)

"""

#########################
g1=filter(lambda n:n%2==0,range(10))
g2=map(lambda n:n*2,range(3))
for i in g1:
    for j in g2:
        print(i*j)   # 0 0 0
生成器
class A:
    a=0.8
    def __init__(self):
        self.a=0.5
    print(a)   #0.8 注意类的加载顺序,此时还没有A.a
A.a=1
obj=A()
print(A.a,obj.a)  # 1  0.5

###############################
class A:
    d=0.7
    def __init__(self,p):
        self.d=0.2
        self.p=p

    def show_price(self):
        return self.p*self.d

    d=0.5

print(A.d)  #0.5
print(A(10).d) #0.2
print(A(10).show_price()) #2.0


###############################

flag =True
def wrap(func):
    def inner(*args,**kwargs):
        if flag:
            ret = func(*args,**kwargs)
            return ret
    return inner

@wrap
def haha():
    print('haha')
    return True

flag=False
ret=haha()
print(ret)  #None


###############################
类的加载顺序
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#生成器中的元素只能从头到尾取一次,生成器不调用不执行
def multip():
    return [lambda x:i*x for i in range(4)]
print([m(2) for m in multip()])

"""
拆分 1:
"""
def multip():
    fun_list=[]
    for i in range(4):
        fun = lambda x:i*x
        fun_list.append(fun)
    return fun_list
print([m(2) for m in multip()])


"""
拆分 2:
"""
def multip():
    fun_list=[]
    i = 0
    fun = lambda x:i*x
    fun_list.append(fun)

    i = 1
    fun = lambda x:i*x
    fun_list.append(fun)

    i = 2
    fun = lambda x:i*x
    fun_list.append(fun)

    i = 3
    fun = lambda x:i*x
    fun_list.append(fun)

    #此时i已经等于3了,fun_list=[lambda x:i*x,lambda x:i*x,lambda x:i*x,lambda x:i*x]
    #特别注意 lambda一直没有调用。
    return fun_list

print([m(2) for m in multip()])   #  [6, 6, 6, 6]

print(50*'=')
"""
要得到[0,2,4,6],方式1:
"""
def multip():
    for i in range(4):
        yield lambda x:i*x
print([m(2) for m in multip()])  #[0, 2, 4, 6]

"""
要得到[0,2,4,6],方式2:
"""
def multip():
    return (lambda x:i*x for i in range(4))
print([m(2) for m in multip()])

"""
要得到[0,2,4,6],方式3:
"""
def multip():
    return [lambda x,i=i:i*x for i in range(4)]
print([m(2) for m in multip()])  #[0, 2, 4, 6]


def multip():
    for i in range(4):
        def fun(x):
            return x * i
        yield fun
print([m(2) for m in multip()])  #[0, 2, 4, 6]



def multip():
    for i in range(4):
        def fun(x,i=i):
            return x * i
        yield fun
print([m(2) for m in multip()])  #[0, 2, 4, 6]
生成器
原文地址:https://www.cnblogs.com/bubu99/p/11096848.html