Python-日志-day10-2019-08-02

day9-函数

一.匿名函数

1.匿名函数

匿名函数就是没有函数名的函数;匿名函数可以看成是类名是function的值和10,‘abc’是同类东西
注意:匿名函数本质还是函数,函数中除了声明语法以外其他的都使用匿名函数
(1)语法
lambda 参数列表:返回值
(2)说明
lambda - 关键字
函数名 = 参数列表 - 参数名1,参数名2,....
:-固定
返回值 - 任何有结果的表达式;它是匿名函数的函数体,相当于普通函数中的return语句
调用匿名函数:保存匿名数值的变量(实参列表)
(3)参数
普通函数中除了用'参数名:类型'的形式来指定参数类型以外,其他的语法匿名函数'都支持

# def 函数名(参数列表):
#     函数体
fn1 = lambda x, y: x+y
"""
def fn1(x, y):
    # x=10, y = 30
    return x+y
"""
fn2 = lambda x: print('====')
"""
def fn2(x):
    return print('=====')
"""

print(fn1(10, 30))
print(fn2(10))

100   # int类型的数据
'abc'  # str类型的数据
[1, 2, 3]   # list类型的数据
{'a': 10, 'b': 20}    # dict类型的数据
lambda x: x   # function类型的数据

a = 100
str1 = 'abc'
list1 = [1, 2, 3]
dict1 = {'a': 10, 'b': 20}
fn1 = lambda x: x
print(a + 10, str1.replace('a', 'A'), list1[0], fn1(90))

list2 = [100, 'abc', [1, 2, 3], lambda x: x*2]
print(list2)
print(list2[0] * 10)
print(list2[1][0])
print(list2[-1](12))


sum1 = lambda x, y, z=3: x+y+z
sum3 = lambda *nums: sum(nums)

def sum2(x, y, z=0):
    return x+y+z

print(sum2(10 , 30), sum2(y=20, x=10))
print(sum1(1, 2), sum1(y=2, x=1))
print(sum3(1, 2, 3, 4, 5))

二.变量的作用域

1.变量的作用域:

变量在程序中能够使用的范围

2.全局变量和局部变量

(1)全局变量
没有声明在函数里面或者类里面的变量就是全局变量
作用域:从声明开始到文件结束的任何位置
(2)局部变量
声明在函数中的变量就是局部变量(函数的参数也是声明在函数中的变量,比如形参)
作用域:从声明开始到函数结束的任何位置
(3)函数调用过程(内存):压栈
当调用函数的时候,系统会自动在内存的栈区间为这个函数开辟一个独立的内存区域,用来保存在函数中声明的变量。当函数调用结束,这个内存区域会自动释放。

print('==============全局变量================')
a = 10   # 全局变量

# x是全局变量
for x in range(5):
    if False:
        c = 100
    b = 20   # 全局变量
    print('循环里面:', a)
    print('循环里面:', x)

print('外面:', b)

def func1():
    print('函数里面:', a)
    print('函数里面:', x)
    print('函数里面:', b)


func1()

print('===================局部变量===================')


def func2(x1=10, y1=20):
    z1 = 100
    print('函数内部:', x1, y1, z1)


func2()


# print('函数外部:', x1)   # NameError: name 'x1' is not defined
# print('函数外部:', z1)   # NameError: name 'z1' is not defined

3.global和nonlocal

global和nonlocal是函数中的关键字,和return一样只能在函数体中使用
(1)global - 在函数中声明一个全局变量
global 变量
变量 = 值

(2)nonlocal
在局部的局部中去修改局部变量的值
nonlocal 变量
变量 = 值

print('=============global=============')
a1 = 111
b1 = 100


def func3():
    # 这儿是在声明一个局部变量a1
    a1 = 222
    print('函数里面a:', a1)

    # 这儿的b1是全局变量
    global b1
    b1 = 333
    print('函数里面b:', b1)


func3()

print('函数外面a:', a1)
print('函数外面b:', b1)

print('================nonlocal=============')


def func4():
    a2 = 100

    def func5():
        nonlocal a2
        a2 = 500
        print('函数里面的函数里面a2:', a2)

    func5()

    print('函数里面a2:', a2)


func4()
# print(a2)    # NameError: name 'a2' is not defined



def func(str):
    # str = 'abc'
    sum = 0

func('hello world!')

print(str(100))

三.函数递归

1.什么是递归函数

自己调用自己的函数(函数体中调用当前函数)
循环能做的事情,递归都可以做
注意:能用循环解决的问题就不要用递归

# def func1():
#     print('=====')
#     func1()
#
#
# func1()`

2.怎么写递归

第一步:找临界值(循环结束的条件)在这儿需要结束函数
第二步:找关系 - 找f(n)和f(n-1)的关系(找当次循环和上次循环的关系)
第三步:假设函数的功能已经实现,根据关系用f(n-1)去实现f(n)的功能

# 用递归函数实现: 1+2+3+...+n
def sum1(n):
    # 第一步: 找临界值
    if n == 1:
        return 1
    # 第二步: sum1(n)和sum1(n-1)
    # sum1(n) == 1+2+3+...+n-1+n
    # sum1(n-1) == 1+2+3+ ... + n-1
    # sum1(n) = sum1(n-1) + n
    return sum1(n-1)+n


print(sum1(100))


# 用递归函数求斐波那契数列中第n个数: 1, 1, 2, 3, 5, 8, 13, 21,...
def sequence(n):
    if n == 1 or n == 2:
        return 1
    # 找关系:sequence(n)和sequence(n-1)
    # sequence(n) = sequence(n-1) + sequence(n-2)
    return sequence(n-1) + sequence(n-2)


print(sequence(1), sequence(2))
print(sequence(8))

# 练习: 用递归实现以下功能
"""
n = 5
*****
****
***
**
*

n=4
****
***
**
*
"""


def print_star(n):
    if n == 1:
        print('*')
        return
    # 找关系: 打印n个*, 再实现f(n-1)的功能
    print(n * '*')
    print_star(n-1)


print_star(3)


# 练习: 用递归实现以下功能
"""
n=3
*
**
***

n=4
*
**
***
****
"""

四.迭代器

1.迭代器(iter)

迭代器作为容器可以保存多个数据;数据的来源:
(1)将其他序列转化成迭代器
(2)生成器

# 1)将其他序列转换成迭代器
iter1 = iter('abc')
print(iter1, type(iter1))

iter2 = iter([12, 30, 90])
print(type(iter2))

2.获取元素

不管用哪种方式去获取了元素的值,那么这个元素在迭代器中就不存在了
(1)获取单个元素:next(迭代器),迭代器.next() --->获取迭代器中的第一个元素
(2)遍历:
for 变量 in 迭代器:

iter3 = iter('hello')
print(next(iter3))
print(next(iter3))
print(next(iter3))
print(iter3.__next__())

# for x in range(100):
#     print(x)

print(next(iter3))
# print(next(iter3))   # StopIteration  如果迭代器为空,用next获取元素的时候会报错

iter4 = iter('world')
for x in iter4:
    print(x)

# print(next(iter4))    # StopIteration

print('===============')
iter4 = iter('world')
print(next(iter4))

for x in iter4:
    print('循环:', x)

五.生成器

1.什么是生成器

(1)生成器就是迭代器中的一种;
(2)调用一个带有yield关键字的函数就可以得到一个生成器
如果一个函数中有yield的关键字:
a. 调用函数不会执行函数体
b.函数调用表达式的值不是函数的返回值而是一个生成器对象

# 1.怎么去创建一个生成器
def func1():
    print('=======')
    if False:
        yield
    return 100


gen1 = func1()    # 这儿的gen1就是一个生成器对象
print('外部:', gen1)

2.生成器产生数据的原理

(1)一个生成器能够产生多少数据,就看执行完生成器对应的函数的函数体会遇到几次yield
yield后面的值就是生成器能够产生的数据
(2)每次获取生成器中的元素的时候,都是先去执行函数体,直到遇到yield,并且将yield后面的值作为元素的结果,并且保留结束的位置,下次获取下一个值的时候,从上次结束的位置接着执行函数体,直到遇到yield。如果从开始执行到函数结束,都没有遇到yield,就会报错stopIteration错误

print('================2==========')


def func2():
    print('+++++')
    yield 1
    print('-----')
    yield 100     # yield 后边可以跟数据;同一个函数可以有多个yield


gen2 = func2()
print(gen2)

print('函数外部:', next(gen2))
print('函数外部:', next(gen2))
# print('函数外部:', next(gen2))   # StopIteration


def func3():
    print('第一段代码')
    yield
    print('第二段代码')
    yield
    print('第三段代码')
    yield


gen3 = func3()

time.sleep(1)
next(gen3)
time.sleep(1)
next(gen3)
time.sleep(1)
next(gen3)


# 练习:
def func4():
    # x = 0
    for x in range(0, 100, 3):
        yield x


print(next(func4()))
print(next(func4()))
print(next(func4()))
gen4 = func4()
print(next(gen4))   # 0
print(next(gen4))   # 3
print(next(gen4))

六.生成式


# 1.生成式
"""
生成式就是生成器的简写

1)语法一
生成器 = (表达式 for 变量 in 序列)   

a.说明: 表达式  -  任何有结果的语句; 数据,赋值后的变量,非赋值的运算表达式等...
b.展开成生成器:
def 函数名():
    for 变量 in 序列:
        yield 表达式      
生成器 = 函数名()


"""
# 1.用生成式创建生成器
gen = (x*2 for x in 'hello')
print(type(gen))   # 
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
# print(next(gen))    # StopIteration

# 2. 列表生成式
list1 = list(x for x in range(5))
print(list1)

list2 = [x for x in 'abc']
print(list2)

gen2 = (x*10 for x in range(5))
list2 = list(gen2)
print(list2)
# print(next(gen2))   # StopIteration

def yt_list(seq):
    temp = []
    for item in seq:
        temp.append(item)
    return temp


# 3.字典生成式
dict1 = dict((x, x*2) for x in range(5))
print(dict1)   # {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}

"""
2) 语法二:
生成器 = (表达式 for 变量 in 序列 if 条件语句)

a.展开成函数
def 函数名():
    for 变量 in 序列:
        if 条件语句:
            yield 表达式
生成器 = 函数名()
"""
gen3 = (x for x in range(10) if x % 2)

"""
def func():
    for x in range(10):
        if x % 2:
            yield x
gen3 = func()
"""
print(list(gen3))


# 补充: python中的三目运算符
"""
C、java、js等中的三目运算符: 变量 = 条件语句?表达式1:表达式2
python中的三目运算符: 变量 = 表达式1 if 条件语句 else 表达式2

三目运算符的功能: 判断条件语句是否为True, 如果是结果是表达式,否则结果是表达式2
"""
a = 19
# num = None
# if a & 1:
#     num = '奇数'
# else:
#     num = '偶数'
num = '奇数' if a & 1 else '偶数'
print(num)


# 练习: 使用生成式写一个生产器,能够产生1~10中所有的数能否被3整除的结果
# 1 -> False  2 - > False  3 -> True  4 -> False, ...

gen4 = (True if num % 3 == 0 else False for num in range(1, 11))
print(list(gen4))  # [False, False, True, False, False, True, False, False, True, False]

你可能感兴趣的:(Python-日志-day10-2019-08-02)