Questions

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#生成器中的元素只能從頭至尾取一次,生成器不調用不執行
g1 = filter(lambda n:n%2==0,range(10))
g2 = map(lambda n:n*2,range(3))

print(list(g1),g1)  #[0, 2, 4, 6, 8]
print(list(g2),g2)  #[0, 2, 4]

for i in g1:
    for j in g2:
        print(i,j)
        print(i*j)   # 000


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]


"""
要獲得[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()])
生成器
#!/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) #['麻花藤']
列表
#! /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
二分法
相關文章
相關標籤/搜索