集合与函数

集合

主要作用:

1去重

2.关系测试

a = {1, 3, 5, 7, 8, 9}
b = {2, 5, 6, 7, 8, 9}

交集
print(a & b)  或 print(a.intersection(b))
{8, 9, 5, 7}

差集
print(a - b)   或 print(a.difference(b))
{1, 3}

并集
print(a | b)   或 print(a.union(b))
{1, 2, 3, 5, 6, 7, 8, 9}

反向对称差集(并集-交集)
print(a ^ b)
{1, 2, 3, 6}

直接用a与b的差集更新a
a.difference_update(b)
print(a)
{1, 3}
print(b)
{2, 5, 6, 7, 8, 9}

 函数

1.减少重复代码

2.易扩展、易维护

函数有两种参数

1.形参:只有在被调用时才分配内存,调用结束后立刻释放内存,值仅在函数内部有效(局部变量,形参的作用域只在当前函数内部)

2.实参:有确定的值参数,所有的数据类型都可以被当做参数传给参数。

局部变量和全局变量

局部变量:作用域只在当前函数内部,外部变量默认不能被函数内部修改,只能引用。

全局变量:如果在函数内部修改函数外部的全局变量,必须使用global。

def change(n):
    print(n)                # 引用的全局变量
    n = "局部变量"          # 局部变量
    print(n)

n = '全局变量'
change(n)
print(n)

全局变量
局部变量
全局变量


def change(n): print(n) # 引用的全局变量 global k k = "局部变量" # 局部变量 print(k) k = '全局变量' change(k) print(k) 全局变量 局部变量 全局变量

函数内部可以修改列表,字典,集合和实例

def change(n):
    print(n)                    # 引用的全局变量
    n.append('Anna')         # 局部变量
    print(n)

n = ['Jack', 'Mike']
change(n)
print(n)

['Jack', 'Mike']
['Jack', 'Mike', 'Anna']
['Jack', 'Mike', 'Anna']


def change(n):
print(n) # 引用的全局变量
n['Anna'] = 40 # 局部变量
del n['Mike'] # 局部变量
n['Jack'] = 50
print(n)

n = {'Jack': 20, 'Mike': 30 }
change(n)
print(n)

{'Jack': 20, 'Mike': 30}
{'Jack': 50, 'Anna': 40}
{'Jack': 50, 'Anna': 40}

 函数参数类型

位置参数/默认参数/关键参数/非固定参数 

位置参数:按照参数的顺序传入函数。

def register_stu(name, age, add):
    print(name, age, add)

register_stu('jack', '25', 'beijing')
register_stu('25', 'jack', 'beijing')
register_stu('beijing', '25', 'jack')

jack 25 beijing
25 jack beijing
beijing 25 jack

 默认参数:默认参数必须在位置参数的后面

def register_stu(name, age, add, country='CN'):
    print(name, age, add, country)

register_stu('jack', '25', 'beijing')
jack 25 beijing CN

 关键参数:正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。

def register_stu(name, age, add, country='CN'):
    print(name, age, add, country)

register_stu(name='jack', age='25', add='beijing')
register_stu(add='beijing', name='jack', age='25')
register_stu(add='beijing', age='25', name='jack')

jack 25 beijing CN
jack 25 beijing CN
jack 25 beijing CN

非固定参数:若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数。

*args

def stu_register(name, age, *args):            # *args 会把多传入的参数变成一个元组形式
    print(name, age, args)

stu_register('Jack', 31, 'CN', 'Python')
Jack 31 ('CN', 'Python')

**kwargs

def stu_register(name, age, *args, **kwargs):  # *kwargs 会把多传入的参数变成一个dict形式
    print(name, age, args, kwargs)

stu_register('Jack', 32)
stu_register('Jack', 32, 'CN', 'Python', sex='Male', province='Beijing')

Jack 32 () {}
Jack 32 ('CN', 'Python') {'sex': 'Male', 'province': 'Beijing'}

 嵌套函数:指的是在一个函数内部调用其他函数。

name = "user"

def change_name():
    name = "user1"

    def change_name2():
        name = "user2"
        print('第3层打印', name)

    change_name2()
    print('第2层打印', name)


change_name()
print('最外层打印', name)

第3层打印 user2
第2层打印 user1
最外层打印 user

调用change_name2()会提示对象没有定义,即不能直接调用嵌套中的函数。

Traceback (most recent call last):
  File "/Users/yangjian/PycharmProjects/S16/day3/嵌套函数.py", line 21, in <module>
    change_name2()
NameError: name 'change_name2' is not defined

 递归函数

在函数里面调用自己本身,这个函数就是递归函数。

每递归一次相当于往列表里append一个值,退出的时候相当于从列表里pop出一个值

 递归特性:

 1.必须有一个明确的结束条件

2.每次进入更深一层递归是,问题规模比上次递归都应该有所减少

3.递归效率不高,递归层次过多会导致栈溢出

def calc(n):
    print(n)           #此时n依次地等于10,5,2,1
    if int(n/2) > 0:
        calc(int(n/2))
    print(n)           #此时n依次地等于1,2,5,10
calc(10)             

10   
5
2
1
1
2
5
10

递归函数举例:从1到100亿的数字里查找99

num = range(1, 10000000000, 2)

def binary_search(find_num, num_set, count):
    mid = int(len(num_set)/2)  # 拿到里中间的下标
    if mid == 0:  # 列表值剩下一个了,没必要继续找了
        if num_set[mid] == find_num:
            print('find it...\033[32m%s\033[0m , times %s' % (find_num, count+1))
        else:
            print('can\'t find the num \033[32m%s\033[0m , times %s' % (num_set[0:mid], count+1))
        return

    if num_set[mid] == find_num:
        print('find it...\033[32m%s\033[0m , times %s' % (find_num, count + 1))

    elif num_set[mid] > find_num:
        print('going to search in left \033[32m%s\033[0m, times %s' % (num_set[0:mid], count+1))
        binary_search(find_num, num_set[0:mid], count+1)

    else:
        print('going to search in right \033[32m%s\033[0m, times %s' % (num_set[0:mid], count+1))
        binary_search(find_num, num_set[mid+1:], count+1)

binary_search(99, num, 0)


going to search in left range(1, 5000000001, 2), times 1
going to search in left range(1, 2500000001, 2), times 2
going to search in left range(1, 1250000001, 2), times 3
going to search in left range(1, 625000001, 2), times 4
going to search in left range(1, 312500001, 2), times 5
going to search in left range(1, 156250001, 2), times 6
going to search in left range(1, 78125001, 2), times 7
going to search in left range(1, 39062501, 2), times 8
going to search in left range(1, 19531251, 2), times 9
going to search in left range(1, 9765625, 2), times 10
going to search in left range(1, 4882813, 2), times 11
going to search in left range(1, 2441407, 2), times 12
going to search in left range(1, 1220703, 2), times 13
going to search in left range(1, 610351, 2), times 14
going to search in left range(1, 305175, 2), times 15
going to search in left range(1, 152587, 2), times 16
going to search in left range(1, 76293, 2), times 17
going to search in left range(1, 38147, 2), times 18
going to search in left range(1, 19073, 2), times 19
going to search in left range(1, 9537, 2), times 20
going to search in left range(1, 4769, 2), times 21
going to search in left range(1, 2385, 2), times 22
going to search in left range(1, 1193, 2), times 23
going to search in left range(1, 597, 2), times 24
going to search in left range(1, 299, 2), times 25
going to search in left range(1, 149, 2), times 26
going to search in right range(1, 75, 2), times 27
going to search in left range(77, 113, 2), times 28
going to search in right range(77, 95, 2), times 29
going to search in left range(97, 105, 2), times 30
going to search in left range(97, 101, 2), times 31
find it...99 , times 32

 匿名函数 临时使用的函数,用完就扔,最复杂的运算就是三元运算

def calc(n, y):
    return n ** y

print(calc(10,12))

1000000000000

calc2 = lambda n, y: n**y
print(calc2(10, 12))

1000000000000

for i in map(lambda x: x+1, [1, 2, 3]):
    print(i)

2
3
4 

高阶函数

特点

1.把一个函数的内存地址传给另外一个函数当做参数

2.把另外一个函数当做返回值返回

def add(x, y, f):
    return f(x) + f(y)

res = add(3, -5, abs)
print(res)

8

返回值

要想获取函数的执行结果,就可以用return语句把结果返回

注意:

  1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
  2. 如果未在函数中指定return,那这个函数的返回值为None 

 

 

 

posted on 2017-01-31 21:42  就是稳稳地  阅读(193)  评论(0编辑  收藏  举报