饮冰三年-人工智能-Python-14Python基础之变量与函数

一、函数:函数是逻辑结构化和过程化的一种编程方法。函数即变量


 1:可变参数

#参数组:**字典   *列表
def test(x,*args):
    print(args);
    print(args[0]);
    print("--------");
test(1,2,3,4,5);
# (2, 3, 4, 5)
# 2
# --------
test(1,[2,3,4,5]);
# ([2, 3, 4, 5],)
# [2, 3, 4, 5]
# --------
test(1,*[2,3,4,5]);
# (2, 3, 4, 5)
# 2
# --------

def test2(x,**kwargs):
    print(kwargs);
    print("--------");

test2(1,y=2,z=3)
# {'y': 2, 'z': 3}
# --------
def test3(x,*args,**kwargs):
    print(args);
    print(kwargs);
    print("--------");

test3(1,4,5,6,y=2,z=3)
# (4, 5, 6)
# {'y': 2, 'z': 3}
# --------
test3(1,*[4,5,6],**{"y":"2","z":"3"})
# (4, 5, 6)
# {'y': 2, 'z': 3}
# --------
View Code

  总结:在python中可以动态的接收参数, *接收位置参数,**来接收动态关键字参数

       Default values are computed once, then re-used.默认值参数只被执行1次

2:命名空间与作用域

  在python解释器开始执⾏之后, 就会在内存中开辟⼀个空间, 每当遇到⼀个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表⽰这个函数存在了, ⾄于函数内部的变量和逻辑, 解释器是不关⼼的. 也就是说⼀开始的时候函数只是加载进来, 仅此⽽已, 只有当函数被调⽤和访问的时候, 解释器才会根据函数内部声明的变量来进⾏开辟变量的内部空间. 随着函数执⾏完毕, 这些函数内部变量占⽤的空间也会随着函数执⾏完毕⽽被清空. 

#locals() 查看局部作用域内的变量
#globals() 查看全局作用域内的变量
A="全局变量"
def part():
    b="局部变量"
    print(locals())
    #{'b': '局部变量'} 
    print(globals())
    '''
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0184D250>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Code/AaronScrapy/AaronScrapyCode/test.py', '__cached__': None, 'A': '全局变量', 'part': <function part at 0x0354EF60>}
    '''
part()
locals() 与 globals()

总结:locals() 查看局部作用域内的变量;globals() 查看全局作用域内的变量 

b="全局变量"
def partB():
    b="B作用域变量"
    print(b)
partB()
print(b)
'''
B作用域变量
全局变量
结论一:各个作用域使用各自区域内的变量,
'''
def partC():
    b="C作用域变量"
    def partD():
        print(b)
    partD()
    print(b)
partC()
print(b)
'''
C作用域变量
C作用域变量
全局变量
结论二:各个作用域使用各自区域内的变量,如果没有,去最近区域内找
'''
def partD():
    global b
    print(b)
    b="在D作用域中修改"
partD()
print(b)
'''
全局变量
在D作用域中修改
结论二:global可以把作用域之间的界限打通,直接使用全局能量,如果修改,也会影响全局
'''
b="全局变量"
def partE():
    b="E作用域变量"
    def partF():
        nonlocal b
        print(b)
    partF()
    print(b)
partE()
print(b)
'''
全局变量
在D作用域中修改
结论二:nonlocal可以把最近存在该变量作用域之间的界限打通,直接使用该能量,如果修改,直接影响该变量
'''
global与nonlocal
 总结: 
  1. global表⽰. 不再使⽤局部作⽤域中的内容了. ⽽改⽤全局作⽤域中的变量
  2. nonlocal 表⽰在局部作⽤域中, 调⽤⽗级命名空间中的变量.
  3. 变量使用遵守就近原则

3:递归函数

  递归函数默认深度为999。

def Remainder(num):
    # 短除法取余数,取到商为0,然后反向输出余数
    if(num//2==0):
        print(num % 2);
        return ;
    Remainder(num//2);
    print(num%2);
Remainder(11);
短除法,计算二进制
# 定义一个人员数组,记录问路人
person_list=['Aaron','ZhangSan','LiSi','WangWu','YangKe'];
# 定义一个问路函数
def ask_way(person_list):
    # 每循环一次弹出一个人,如果人员数组中值为空,那么表示没有人知道
    if len(person_list)==0:
        return "没人知道";
    person = person_list.pop(0);
    if person == "YangKe":
        return '%s说:“哦,我知道”' %person;
    print("hi,[%s],敢问路在何方?" % person);
    print("[%s]说:“我不知道,我可以帮你问问%s...”" %(person,person_list));
    res=ask_way(person_list);
    print("%s问的结果是:%res" %(person,res));
    return  res;

result = ask_way(person_list);
print(result);
递归问路
# 根据范围获取其中3和7整除的所有数的和,并返回调用者
# 符合条件的数字个数以及符合条件的数字的总和

# 方法一:通过递归调用
def func(start,end,a=0,su=0):
    if start==end:
        return a,su
    if start%3==0 or start%7==0 :
        a = a + 1;
        su = su +start;
    start = start+1
    return func(start,end,a,su)
resu=func(1,11)
print(resu)

# 方法二:通过for
def func2(start,end,a=0,su=0):
    for i in range(start,end):
        if  i%3==0 or i%7==0 :
            a+=1
            su+=i
    return  a,su
resu=func2(1,11)
print(resu)
根据范围获取其中3和7整除的所有数的和,并返回调用者

4:匿名函数

# 格式 lambda x:返回结果
func = lambda x,y,z:x+y+z;
print(func(1,2,3))
匿名函数

5:常用函数

  5.1 map函数  

# 格式map(函数名,可迭代类型)

# map函数实现原理
def maptest(func,arr):
    # 定义一个新的数组
    restArray=[];
    for i in  arr:
        # 调用传递过来的函数
        result = func(i);
        restArray.append(result);
    return  restArray;

#通过lambda表达式调用
serArray=[15,321,54,86,1,5,9,3,5,4,68];
rest=maptest(lambda x:x+1,serArray);
print(rest);
# 输出结果  [16, 322, 55, 87, 2, 6, 10, 4, 6, 5, 69]

rest2 = map(lambda x:x+1,serArray);
print(list(rest2));
# 输出结果  [16, 322, 55, 87, 2, 6, 10, 4, 6, 5, 69]
map函数 
res=map(lambda x,y:x+y,[1,2,3],[4,5,6])
print(list(res))
# [5, 7, 9]

res=map(lambda x,y:x+y,[1,2,3],[4,5])
print(list(res))
# [5, 7]

def Add(*args):
    sum = 0
    for i in args:
        sum += i
    return sum
res=map(Add,[1,2,3],[4,5,],[7,8,9])
print(list(res))
# [12, 15]
map函数

 5.2 filter函数  

# 定义一个观看电影人员的列表
movie_people=['a_zhangsan','b_zhangsan','a_lisi','b_lisi'];
#定义一个过滤人员的逻辑
def getAPeople(currPeople):
    return currPeople.startswith("a");

def filterTest(funct,array) :
    rest = [];
    for p in array:
        if funct(p):
            rest.append(p);
    return rest;

print(list(filterTest(getAPeople,movie_people)));
# 输出结果 ['a_zhangsan', 'a_lisi']
# 利用系统自带的filter函数
print(list(filter(lambda x:x.startswith("a"),movie_people)));
# 输出结果 ['a_zhangsan', 'a_lisi']
filter函数

   5.3 reduce函数  

# 定义一个数据列表
arr = [1,2,3,4,5,6,7,8,9]
#定义一个处理逻辑
def getSum(sum,x):
    return  sum+x;
# 一共有三个参数:(函数名,可迭代类型,初始值)
def reduceTest(fun,array,init=None):
    if init is None:
        sum = array.pop(0);
    else:
        sum = init;
    for n in array:
        sum = fun(sum,n);
    return  sum;
print(reduceTest(getSum,arr,100));
#print(reduceTest(getSum,arr));

# 注意    1:这里可以设置一个初始值
#         2:需要导入包
from functools import reduce
print(reduce(lambda x,y:x+y,arr,100));
reduce函数

6:内置函数

# 6.1 绝对值
print(abs(-2));
# 输出结果 2

# 6.2  进行布尔运算,一假全假
print(all([1,'0',True]));
# 输出结果 True
print(all([0,'1',True]));
# 输出结果 False

# 6.3  进行布尔运算,一真全真
print(any([0,'1',True]));
# 输出结果 True

# 6.4  进行布尔运算,'' None 0 为false,其余为True
print(bool(None));
# 输出结果 False

# 6.5 bytes
print(bytes("zhang三",encoding="utf-8"));
# 输出结果 b'zhangxe4xb8x89'
print(bytes("zhang三",encoding="utf-8").decode("utf-8"));
# 输出结果 zhang三

# 6.6 ASCII 转化
print(chr(97));
# 输出结果 a

# 6.7 dir 查看对象下的方法
print(dir(all));
# 输出结果 ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']

# 6.8 divmod 分页常用(一共多少条记录,每页多少条记录)
print(divmod(101,10));
# 输出结果 (10, 1)

# 6.9 eval 很强大
# 6.9.1 将字典类型的字符串转化成字典
dicStr = '{"name":"张三"}';
d1 = eval(dicStr);
print(d1['name']);
# 输出结果 张三

# 6.9.2 将字符串形式的表达式进行计算
calStr = '1+2*(3+4)';
print(eval(calStr));
# 输出结果 15

# 6.10 hash() 可hash即不可变数据类型
print(hash("张三"));
# 输出结果 1381178516053414445

# 6.11 进制转换
print(bin(10));# 10进制==》2进制   # 输出结果 0b1010
print(hex(12));# 10进制==》16进制  # 输出结果 0xc
print(oct(12));# 10进制==》8进制  # 输出结果 0o14

# 6.12  判断是否是该类的实例
print(isinstance(1,int));  # 输出结果  True
print(isinstance([],list));# 输出结果  True

# 6.13 globals();
def test():
    age="11";
    print(globals());
    print(locals());
test();
# 输出结果{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000000527C50>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Code/内置函数.py', '__cached__': None, 'dicStr': '{"name":"张三"}', 'd1': {'name': '张三'}, 'calStr': '1+2*(3+4)'}
# 输出结果 {'age': '11'}
内置函数
# 6.14 zip函数,拉链函数
print(list(zip(('a','b','c'),(1,2,3,4))))
# 输出结果 [('a', 1), ('b', 2), ('c', 3)]
p = {'name':'张三','age':15}
print(list(zip(p.keys(),p.values())))
# 输出结果 [('name', '张三'), ('age', 15)]

# 6.15 最大最小值
# 6.15.1 计算数值列表中的最大值
lis = [1,3,100,-5,50];
print(max(lis));# 输出结果 100
print(min(lis));# 输出结果 -5
# 6.15.2 计算字典中的最大值,并返回姓名
age_dic = {'张三':1,'李四':3,'王五':100,'小刘':-5,'天启':50};
# 方法一
print(max(zip(age_dic.values(),age_dic.keys())));
# 输出结果  (100, '王五')
# 方法二
print(max(age_dic,key=lambda  key:age_dic[key]));
# 输出结果  王五
people = [
    {'name':"aaron","age":15},
    {'name':"yangKe","age":25},
    {'name':"yangXiaoKe","age":27}
];
print(max(people,key=lambda dic:dic["age"]));
# 输出结果 {'name': 'yangXiaoKe', 'age': 27}

# 6.16 chr与ord
print(chr(97)); # 输出结果  a
print(ord('a'));# 输出结果  97

# 6.17 pow
print(pow(2,3)); # 输出结果  8
print(pow(2,3,2));# 输出结果  0  2**3%2

# 6.18 反转
l=[1,2,3,4]
print(list(reversed(l))); # 输出结果  [4, 3, 2, 1]

# 6.19  round保留小数位数
print(round(3.141592,5)); # 输出结果  3.14159

# 6.20  set可以用来去重复
print(set('hello')); # 输出结果  {'e', 'o', 'l', 'h'}

# 6.21 切片
ll='hello';
s1=slice(3,5);
s2=slice(1,4,2);
print(ll[s1]); # 输出结果  lo
print(ll[s2]); # 输出结果  el

# 6.22  sorted 排序
people = [
    {'name':"aaron","age":35},
    {'name':"yangKe","age":25},
    {'name':"yangXiaoKe","age":27}
];
print(sorted(people,key=lambda dic:dic['age']));
# 输出结果  [{'name': 'yangKe', 'age': 25}, {'name': 'yangXiaoKe', 'age': 27}, {'name': 'aaron', 'age': 35}]
people2 = [
    {"aaron":35,
    "yangKe":25,
    "yangXiaoKe":27}
];
print(sorted(zip(people2[0].values(),people2[0].keys())));
# 输出结果  [(25, 'yangKe'), (27, 'yangXiaoKe'), (35, 'aaron')]

# 6.23  把其他形式转换成字符串
dic_str=str({"a":"1"});
print(dic_str); # 输出结果 {'a': '1'}
print(eval(dic_str));# 输出结果 {'a': '1'}

# 6.24  vars
def test():
    msg="abc";
    print(locals());
    print(vars());
test();
print(vars(int));

# 输出结果 {'msg': 'abc'}
# 输出结果 {'msg': 'abc'}
# 输出结果  {'__repr__': <slot wrapper '__repr__' of 'int' objects>, '__hash__': <slot wrapper '__hash__' of 'int' objects>, '__str__': <slot wrapper '__str__' of 'int' objects>, '__getattribute__': <slot wrapper '__getattribute__' of 'int' objects>, '__lt__': <slot wrapper '__lt__' of 'int' objects>, '__le__': <slot wrapper '__le__' of 'int' objects>, '__eq__': <slot wrapper '__eq__' of 'int' objects>, '__ne__': <slot wrapper '__ne__' of 'int' objects>, '__gt__': <slot wrapper '__gt__' of 'int' objects>, '__ge__': <slot wrapper '__ge__' of 'int' objects>, '__add__': <slot wrapper '__add__' of 'int' objects>, '__radd__': <slot wrapper '__radd__' of 'int' objects>, '__sub__': <slot wrapper '__sub__' of 'int' objects>, '__rsub__': <slot wrapper '__rsub__' of 'int' objects>, '__mul__': <slot wrapper '__mul__' of 'int' objects>, '__rmul__': <slot wrapper '__rmul__' of 'int' objects>, '__mod__': <slot wrapper '__mod__' of 'int' objects>, '__rmod__': <slot wrapper '__rmod__' of 'int' objects>, '__divmod__': <slot wrapper '__divmod__' of 'int' objects>, '__rdivmod__': <slot wrapper '__rdivmod__' of 'int' objects>, '__pow__': <slot wrapper '__pow__' of 'int' objects>, '__rpow__': <slot wrapper '__rpow__' of 'int' objects>, '__neg__': <slot wrapper '__neg__' of 'int' objects>, '__pos__': <slot wrapper '__pos__' of 'int' objects>, '__abs__': <slot wrapper '__abs__' of 'int' objects>, '__bool__': <slot wrapper '__bool__' of 'int' objects>, '__invert__': <slot wrapper '__invert__' of 'int' objects>, '__lshift__': <slot wrapper '__lshift__' of 'int' objects>, '__rlshift__': <slot wrapper '__rlshift__' of 'int' objects>, '__rshift__': <slot wrapper '__rshift__' of 'int' objects>, '__rrshift__': <slot wrapper '__rrshift__' of 'int' objects>, '__and__': <slot wrapper '__and__' of 'int' objects>, '__rand__': <slot wrapper '__rand__' of 'int' objects>, '__xor__': <slot wrapper '__xor__' of 'int' objects>, '__rxor__': <slot wrapper '__rxor__' of 'int' objects>, '__or__': <slot wrapper '__or__' of 'int' objects>, '__ror__': <slot wrapper '__ror__' of 'int' objects>, '__int__': <slot wrapper '__int__' of 'int' objects>, '__float__': <slot wrapper '__float__' of 'int' objects>, '__floordiv__': <slot wrapper '__floordiv__' of 'int' objects>, '__rfloordiv__': <slot wrapper '__rfloordiv__' of 'int' objects>, '__truediv__': <slot wrapper '__truediv__' of 'int' objects>, '__rtruediv__': <slot wrapper '__rtruediv__' of 'int' objects>, '__index__': <slot wrapper '__index__' of 'int' objects>, '__new__': <built-in method __new__ of type object at 0x000007FEF26161E0>, 'conjugate': <method 'conjugate' of 'int' objects>, 'bit_length': <method 'bit_length' of 'int' objects>, 'to_bytes': <method 'to_bytes' of 'int' objects>, 'from_bytes': <method 'from_bytes' of 'int' objects>, '__trunc__': <method '__trunc__' of 'int' objects>, '__floor__': <method '__floor__' of 'int' objects>, '__ceil__': <method '__ceil__' of 'int' objects>, '__round__': <method '__round__' of 'int' objects>, '__getnewargs__': <method '__getnewargs__' of 'int' objects>, '__format__': <method '__format__' of 'int' objects>, '__sizeof__': <method '__sizeof__' of 'int' objects>, 'real': <attribute 'real' of 'int' objects>, 'imag': <attribute 'imag' of 'int' objects>, 'numerator': <attribute 'numerator' of 'int' objects>, 'denominator': <attribute 'denominator' of 'int' objects>, '__doc__': "int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4"}

# 6.24  import
import say
say.sayHello();
# 输出结果 Hello
module_name="say";
m=__import__(module_name);
m.sayHello();
# 输出结果 Hello
内置函数2

7:Python函数传参是传值还是传引用  

def change(val):
     val=10
nums = 1
change(nums)
print(nums)

#输出结果为 1



def change(val):
    val.append(100)
    val = ['x', 'y', 'z']
nums = [0, 1]
change(nums)
print(nums)

#输出结果为【0,1,100】
View Code

 Python中函数参数的传递是传递的变量的值,即就是变量所指向的对象的地址

一般的,我们有下面的规律:
1. 不可变对象作为函数参数,相当于C系语言的值传递。

2. 可变对象作为函数参数,相当于C系语言的引用传递。

3.一旦函数中遇到=,就会重新开辟一个内存空间,不再对传递过来的参数有影响

8:练习

a = 1                            # 执行顺序  1
def fun_1():                     # 执行顺序  2
    a = 2                           # 执行顺序  5
    def fun_2():                    # 执行顺序  6
        nonlocal a                      # 执行顺序  9   注意:nonlocal用法是获取最近区域的a值。也就是第三行a等于2
        a = 3                           # 执行顺序  10  注意:此时修改同时修改第三行a。等于3
        def fun_3():                    # 执行顺序  11
            a = 4                           # 执行顺序  14
            print(a)                        # 执行顺序  15       输出:4
        print(a)                        # 执行顺序  12        输出:3
        fun_3()                         # 执行顺序  13
        print(a)                            # 执行顺序  16       输出:3
    print(a)                        # 执行顺序  7      输出:2
    fun_2()                         # 执行顺序  8
    print(a)                                # 执行顺序  17       输出:3
print(a)                        # 执行顺序  3       输出:1
fun_1()                         # 执行顺序  4
print(a)                                     # 执行顺序  18      输出:1

'''
1
2
3
4
3
3
1
'''
练习1:函数输出结果
# 1*2*3*4*5*6*7=5040
# 方法一 利用递归实现
def getCul(start,end,cul=1):
    cul = cul * start
    if start==end:
        return cul
    start=start+1
    return  getCul(start,end,cul)
print(getCul(1,7))
# 方法二  利用递归实现
def f(n):
    if n==1:
        return 1
    return n*f(n-1)
print(f(7))
# 方法三  利用for循环实现
def getCul2(start,end):
    cul = 1
    for i in range(start,end):
        cul = cul * i
    return  cul
print(getCul2(1,8)) # 注意range方法顾头不顾尾
# 方法四  利用reduce和lambda表达式
from functools import reduce
print(reduce(lambda x,y :x*y,[x for x in  range(1,8)]))
练习2:求阶乘
def addList(par,list=[]):
    list.append(par)
    return list

l1=addList(11)
l2=addList(22,[])
l3=addList("33")

print(l1)
print(l2)
print(l3)


'''
[11, '33']
[22]
[11, '33']

'''
练习3:默认值参数
原文地址:https://www.cnblogs.com/YK2012/p/9656809.html