2019-05-18

Python学习

函数

  • 变长参数 *a, 以元组传入
    参数用 *a ,输入的参数会以元组形式传入
def self_print(*a):
    print(a)
    print(type(a))
self_print(1,2,3,4,5,'a','c','s')
#(1, 2, 3, 4, 5, 'a', 'c', 's')
#

也可以普通参数和变长参数同时使用
参数按位置传递,最后的都放在变长参数里
但是变长参数一定要放在最后

def self_print(b,*a):
    print(a)
    print(type(a))
self_print(1,2,3,4,5,'a','c','s')
#(2, 3, 4, 5, 'a', 'c', 's')
#

变长参数不放在最后会报错

def self_print(*a,b):
    print(a)
    print(type(a))
self_print(1,2,3,4,5,'a','c','s')
#TypeError: self_print() missing 1 required keyword-only argument: 'b'
  • 变长参数 **a, 以字典传入
    参数用 **a ,输入的参数会以字典形式传入
def self_print(**a):
    print(a)
    print(type(a))
self_print(first_name='tf',last_name='xu')
#{'first_name': 'tf', 'last_name': 'xu'}
#
  • 变长参数,混合使用
    参数位置不能乱,必须形参顺序:位置参数,元组,字典
    传入时参数也不能乱
def self_print(a,*b,**c):
    print(a)
    print(type(a))
    print(b)
    print(type(b))
    print(c)
    print(type(c))
self_print('ab',290,12,'a',first_name='tf',last_name='xu')
#ab
#
#(290, 12, 'a')
#
#{'first_name': 'tf', 'last_name': 'xu'}
#

如果有关键字参数或默认参数时:
有默认参数时,会因为自动的按顺序传,默认参数会用不到
应该不能另外传其他关键字参数,因为**本来就是传入关键字参数的字典

  • 拆开输出的元组和列表 *a
a=(91,2,3,4,5)
print(*a)
#91 2 3 4 5
a=[91,2,3,4,5]
print(*a)
#91 2 3 4 5
a={'a':1,'b':2}
print(*a)
#a b

[序列解包]序列解包没有 **。

>>> a, b, *c = 0, 1, 2, 3  
>>> a  
0 
 >>> b 
 1  
>>> c  
[2, 3]
  • 拆开字典 **a
    在输入函数的时候用
def ff(**keyword):
    print(keyword)
ff(**{'a':1,'b':2})
#{'a': 1, 'b': 2}

报错

a={"name":1,'bv':2}
print(**a)
#TypeError: 'name' is an invalid keyword argument for print()

-函数传参 引用类型 普通类型
python中的基本类型都是普通类型.数,布尔型,字符串型
除这些之外都是引用类型
程序内存分析网站:pythontutor.com

  • 引用类型
    传输的时候传输的是地址
l1=[1,2,3,4,5]
l2=l1
l2[0]=0
print(l1)
#[0, 2, 3, 4, 5]
  • 普通类型
    传输的时候传的是值
a=5
b=a
b=10
print(a)
#5
  • 函数传参
    传参的本质是赋值操作,如果传递的是引用类型数据,则需要注意是否在函数中对其作了修改
    防止做修改,可以在函数内先创建副本:
    用:numbers=numbers[:]
    或:numbers=list(umbers)
def power(numbers):
    numbers=[x**2 for x in numbers]
    numbers[3]=3333
    return numbers
nums=[1,2,3,4,5]
print(power(nums))
print(nums)
#1, 4, 9, 3333, 25]
#1, 2, 3, 4, 5]

若想让原来的列表被改变,就让函数直接更改(不要生成新的)比如用for循环,就会把这个引用类型直接也改了

def power(numbers):
    #numbers=list(numbers)
    #numbers=[x**2 for x in numbers]
    for i,x in enumerate(numbers):
        numbers[i] = x ** 2
    # numbers[3]=3333
    return numbers

nums=[1,2,3,4,5]
print(power(nums))
print(nums)
#1, 4, 9, 16, 25]
#1, 4, 9, 16, 25]
  • 函数也可以引用
    函数的本质是函数的地址
def fun():
  print("hello world")
f=fun
f()
#hello world
  • 函数的嵌套
    闭包:函数嵌套函数,外层的函数返回内层函数的地址.
    闭包用的时候内层函数不用担心污染外边.
def otter():
    def inner():
        print('hello inner')
    return inner
fo=otter()
fo()
#hello inner
  • 函数的作用域
    变量的作用域是以函数为单位的
def otter():
    a=10
    def inner():
        print(a)
        print('hello inner')
    return inner
fo=otter()
fo()
#10
#hello inner
def otter():
    a=10
    def inner():
        a=20
        print(a)
        print('hello inner')
    print(a)
    return inner
fo=otter()
fo()
#10
#20
#hello inner

内层函数要访问变量时,会先从自己查找,若找不到,会层层向上查找.内层函数若要新创建值,必须在使用前创建

def otter():
    a=10
    def inner():
        print(a)
        print('hello inner')
        a = 20
    print(a)
    return inner
fo=otter()
fo()
#UnboundLocalError: local variable 'a' referenced before assignment

内层函数不能直接更改外层变量,会被认为没有定义.

def otter():
    a=10
    def inner():
        a-=10
        print(a)
        print('hello inner')
    print(a)
    return inner
fo=otter()
fo()
#UnboundLocalError: local variable 'a' referenced before assignment

global 代表最外层的变量

a=10
def otter():
    a=10
    def inner():
        global a
        a-=10
        print(a)
        print('hello inner')
    print(a)
    return inner
fo=otter()
fo()
#10
#0

nonlocal 外面一层变量
若要修改外面一层函数的变量(嵌套层,不一定是最外层的全局变量),用nonlocal

a=30
def otter():
    a=10
    def inner():
        nonlocal a
        a-=10
        print(a,'inner')
        print('hello inner')
    print(a)
    return inner
fo=otter()
fo()
#10
#0 inner
#hello inner

递归

递归

写递归,首先要确定出口,否则就会无线的调用,直到内存溢出.
递归从后往前思考

高阶函数

把函数作为参数传入函数
函数的本质是地址.
在写大的函数的时候,可以把只让变的部分变化,其他的东西不变:策略模式

 handle(func,*param):
    return func(*param)

def my_sum(*param):
    return sum(param)
print(handle(my_sum,1,2,3,4,5))
#15

系统级的高阶函数

  • map函数
    map(func,iterable)#该函数会把i特让步了中的数据依次传递给func函数处理,最后把处理结果返回
#map(func,iterable)
def power(x):
    return x*x

result=map(power,[1,2,3,4,5])
print(result)#因为result是个生成器,所以没法直接输出结果
print(list(result))
#
#[1, 4, 9, 16, 25]
  • zip()
    zip([iterable, ...])
    zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
    如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
  • reduce()
    累计操作,func函数必须接受两个参数,reduce会把func的运行结果作为一个参数,人后从iterable中再取出一个数据作为另一个参数.
    reduce(func,iterable)
from functools import reduce
li=[1,2,3,4,5]
result=reduce(lambda x,y:x*y,li)
print(result)
#120

先把iterable中前两个数据传入x,y,之后把上一次运算的结果当作x,之后在iterable中取一个数据进行计算.
func必须只接受两个参数

  • filter()
    filter(func,iterable)
    柑橘函数func来过滤iterable
    将iterable中的数据传入函数func中,如果函数返回True,则保留该数据,否则不保留.
li=[1,2,3,4,5]
result=list(filter(lambda x:x%2==1,li))
print(result)
#[1, 3, 5]
  • sorted()
    sort(iterable,key=None,reverse=False)
    对主句进行排序,key可以用来指定的规则(注意传入的key函数不要加括号,否则就代表函数的调用.),是一个函数.reverse用来指定排序的顺序,默认False,若为True则倒序.
    sorted()不会改变原来的数据.
li=[-1,3,6,-10]
print(sorted(li))
print(sorted(li,key=abs))#注意传入的key函数不要加括号,否则就代表函数的调用.
print(sorted(li,key=abs,reverse=True))
print(li)
#[-10, -1, 3, 6]
#[-1, 3, 6, -10]
#[-10, 6, 3, -1]
#[-1, 3, 6, -10]

和.sort的不同
.sort会改变原来的数据

li=[-1,3,6,-10]
li.sort()
print(li)
#[-10, -1, 3, 6]

模块

模块就是一个文件,我们在编写程序时,可以把功能相似的代码放到一个模块中

  • 直接用import导入整个模块,可以用as起别名
    import 模块名
    import 模块名 as 别名

  • 用from----import----导入函数
    from 文件名 import 函数名

  • 若从两个文件导入同名函数,可以通过as取别名
    from food import make_pizza as mp
    from pizza import make_pizza
    这样就不会出错

你可能感兴趣的:(2019-05-18)