【python学习笔记】函数

一,函数的分类

#1、内置函数
为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()
#2、自定义函数

很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。

二,定义函数

#语法
def 函数名(参数1,参数2,参数3,...):
    '''注释'''
    函数体
    return 返回的值

#函数名要能反映其意义

定义函数的三种形式:

1.无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印

2.有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值

#定义阶段
def calc(x,y): #有参数
    print(x*y)

def tell_msg(): #无参数
    print('hello world')

#调用阶段
calc(5,8)
tell_msg()

#打印结果
40
hello world
#结论:
#1、定义时无参,意味着调用时也无需传入参数

#2、定义时有参,意味着调用时则必须传入参数

3.空函数:设计代码结构

def auth(user,password):                             
    '''                                                           
    auth function                                                 
    :param user: 用户名                                              
    :param password: 密码                                           
    :return: 认证结果                                                 
    '''                                                           
    pass                                                          
                                                                  
def get(filename):                                                
    '''                                                           
    :param filename:                                              
    :return:                                                      
    '''                                                           
    pass                                                          
                                                                  
def put(filename):                                                
    '''                                                           
    :param filename:                                              
    :return:                                                      
    '''                                                           
def ls(dirname):                                                  
    '''                                                           
    :param dirname:                                               
    :return:                                                      
    '''                                                           
    pass                                                          

三,函数使用规则:先调用,再调用

函数即“变量”,“变量”必须先定义后引用。未定义而直接引用函数,就相当于在引用一个不存在的变量名
#test1
def foo():
    print('from foo')
    bar()
foo() #报错

#test2
def bar():
    print('from bar')
def foo():
    print('from foo')
    bar()
foo() #正常

#test3
def foo():
    print('from foo')
    bar()
    
def bar():
    print('from bar')
foo() #正常


#结论:函数的使用,必须遵循原则:先定义,后调用
#我们在使用函数时,一定要明确地区分定义阶段和调用阶段

#定义阶段
def foo():
    print('from foo')
    bar()
def bar():
    print('from bar')
#调用阶段
foo()

def foo():
    print('from foo')
    bar()
foo()
def bar():
	print('from bar')
#报错

四,函数与过程

1.函数返回值
    ①无return->None
    ②return 1个值->返回1个值

    ③return 逗号分隔多个值->元组

def test01():
    pass
 
def test02():
    return 0
 
def test03():
    return 0,10,'hello',['alex','lb'],{'WuDaLang':'lb'}
 
t1=test01()
t2=test02()
t3=test03()
 
print('from test01 return is [%s]: ' % type(t1),t1)
print('from test02 return is [%s]: ' % type(t2),t2)
print('from test03 return is [%s]: ' % type(t3),t3)

2.过程定义:过程就是简单特殊没有‘返回值’的函数,没有return,默认的返回值为None

def test01():
    msg='hello The little green frog'
    print(msg)
 
def test02():
    msg='hello WuDaLang'
    print(msg)
    return msg
 
t1=test01()
t2=test02()
 
print('from test01 return is [%s]' % t1)
print('from test02 return is [%s]' % t2)

五,参数

1.形参与实参

①形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。
函数调用结束返回主调用函数后则不能再使用该形参变量
②实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,

以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

def calc(x,y):
	res =x*y
	return res
c = calc(5,8)
print(c)

2.位置参数与关键字参数

①位置参数,必须一一对应,缺一行不行,多一行也不行
②关键字参数,无需一一对应,缺一行也不行,多一行也不行

③位置参数必须在关键字参数前面

3.默认参数

def handle(x,type='mysql'):
	print(x)
	print(type)

#handle('hello')
#handle('hello',type='sqlite')
#handle('hello','sqlite')
打印:
hello
sqlite

4.参数组

*:将参数组打包成元组形式

def test(x,*args): #传入多个参数
    print(x)
    print(args)
test(1,2,3,4,5,6)
打印:
1
(2, 3, 4, 5, 6)

test(1)
打印:
1
()
#传入字典参数
def test(x,*args):
    print(x)
    print(args)
test(1,{'name':'alex'})
打印:
1
({'name': 'alex'},)
#传入列表参数
def test(x,*args):
	print(x)
	print(args)
	print(args[0][0])
test(1,['x','y','z'])
打印:
1
(['x', 'y', 'z'],)
x
#传入打包好的列表,解包成元组形式
def test(x,*args):
    print(x)
    print(args)
test(1,*['x','y','z'])
打印:
1
('x', 'y', 'z')
#传入打包好的元组,解包成元组形式
def test(x,*args):
    print(x)
    print(args)
test(1,*('x','y','z'))
打印:
1
('x', 'y', 'z')

*针对位置参数
例如:
def test(x,*args):
    print(x)
    print(args)
test(1,y=2,z=3)
打印:报错
TypeError: test() got an unexpected keyword argument 'y'

**:将参数组打包成字典形式

def test(x,**kwargs):
    print(x)
    print(kwargs)

test(1,y=2,z=3)
#test(1,y=2,z=3,z=4) #报错:一个参数不能传两个值
打印:
1
{'y': 2, 'z': 3}
1
#传入键值对
def test(x,*args,**kwargs):
    print(x)
    print(args)
    print(kwargs)
test(1,2,3,4,5,6,8,1,y=1,z=1)
打印:
1
(2, 3, 4, 5, 6, 8, 1)
{'y': 1, 'z': 1}

def test(x,*args,**kwargs):
    print(x)
    print(args,args[1])
    print(kwargs,kwargs['y'])
test(1,2,3,4,5,6,8,1,y=1,z=1)
打印:
1
(2, 3, 4, 5, 6, 8, 1) 3
{'y': 1, 'z': 1} 1

def test(x,*args,**kwargs):
    print(x)
    print(args,args[1])
    print(kwargs,kwargs.get('y'))
test(1,*[1,2,3],**{'y':1})
打印:
1
(1, 2, 3) 2
{'y': 1} 1

六,函数对象

1.函数是第一类对象,即函数可以当作数据传递
①可以被引用
②可以当作参数传递
③返回值可以是函数
④可以当作容器类型的元素

2.利用该特性,优雅的取代多分支的if

def foo():
    print('foo')

def bar():
    print('bar')

dic={
    'foo':foo,
    'bar':bar,
}
while True:
    choice=input('>>: ').strip()
    if choice in dic:
        dic[choice]()

七,嵌套和作用域

1.嵌套定义

def f1():
    def f2():
        def f3():
            print('from f3')
        f3()
    f2()

f1()
f3() #报错

2.函数嵌套

name = "Alex"
 
def change_name():
    name = "Alex2"
 
    def change_name2():
        name = "Alex3"
        print("第3层打印",name)
 
    change_name2() #调用内层函数
    print("第2层打印",name)
 
 
change_name()
print("最外层打印",name)

3.作用域

①作用域即范围
  - 全局范围
 - 局部范围

②作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下:

x=1
def f1():
    def f2():
        print(x)
    return f2
x=100
def f3(func):
    x=2
    func()
x=10000
f3(f1())
例一:
name='alex'

def foo():
    name='lhf'
    def bar():
        print(name)
    return bar

func=foo()
func()

例二:
name='alex'

def foo():
    name='lhf'
    def bar():
        name='wupeiqi'
        def tt():
            print(name)
        return tt
    return bar

func=foo()
func()()

③查看作用域:globals(),locals()

LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间

builtins 内置模块的名字空间

八,局部变量和全局变量

①在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
②全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
③当全局变量与局部变量同名时-->>在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用

name='lhf'
def change_name():
    print('我的名字',name)
change_name()

def change_name():
    name='帅了一笔'
    print('我的名字',name)
change_name()
print(name)

def change_name():
    global name
    name='帅了一笔'
    print('我的名字',name)
change_name()

九,关键字global和nonlocal

如果函数中无global关键字,优先读取局部变量,能读取全局变量,无法对全局变量重新赋值:
对可变类型,可以对内部元素进行操作

1.有声明局部变量
2.无声明局部变量
如果函数中有global关键字,变量本质上就是全局的那个变量,可读取可赋值:
1.有声明局部变量
2.无声明局部变量
建议:

全局变量用大写字母 局部变量用小写字母

NAME = '大山'

def meinv():
    name = 'huang'
    print(name)
    def shuaige():
	name = 'chen'
        print(name)
	def jiyou():
	    name = 'zhao'
	    print(name)
	jiyou()
	print(name)
    shuaige()
    print(name)
meinv()

#例2
name = '度娘'

def weibo():
	name = 'jiyou'
	def weibobo():
		global name
		name = 'baihe'
		
	weibobo()
	print(name)

print(name)
weibo()
print(name)
#例3
name = '度娘'

def weibo():
    name = 'jiyou'
    def weibobo():
	nonlocal name   #nonlocal关键字,指定上一层变量
	name = 'baihe'		
    weibobo()
    print(name)
print(name)
weibo()
print(name)

十,递归

递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用

递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个
函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会

导致栈溢出)

递归调用应该包含两个明确的阶段:回溯递推
回溯就是从外向里一层一层递归调用下去

回溯阶段必须要有一个明确地结束条件,每进入下一次递归时,问题的规模都应该有所减少(否则,单纯地重复调用自身是毫无意义的)

举例:
# salary(5)=salary(4)+300
# salary(4)=salary(3)+300
# salary(3)=salary(2)+300
# salary(2)=salary(1)+300
# salary(1)=100
#
# salary(n)=salary(n-1)+300     n>1

# salary(1) =100                n=1

#定义一个函数完成上述过程
def salary(n):
    if n == 1:
        return 100
    return salary(n-1)+300
print(salary(5))

问题:python中的递归效率低,需要在进入下一次递归时保留当前的状态,在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己


def calc(n):
    print(n)
    if int(n/2) == 0:
	return n
    return calc(int(n/2))
res = calc(10)
print(res)

打印结果:
10
5
2
1
1
import time

name_list = ['鸡总','老司机','老王','游总']

def request_av(name_list):
    if len(name_list) == 0:
	return '没人有资源'
    person = name_list.pop(0)
    if person == '老王':
	return '你要的资源在我的网盘,网盘号为xxxxx'
    print('饥渴男问:请问你有没有资源')
    print('%s回答:我没有资源,但是你可以找%s' % (person,name_list))
    time.sleep(5)
    res = request_av(name_list)
    return res

res = request_av(name_list)
print(res)
ls = []

def test(n):
    n = int(n/2)
    ls.append(n)
    if int(n/2) == 1:
	return ls
    return test(n)

print(test(101))

二分法-->>递归应用实例

想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]

def datacheck(dataset,find_num):
    if len(dataset) > 1:
	print('你要的数字可能有')
	mid = int(len(dataset)/2)
	if dataset[mid] == find_num:
	    print('找到了')
	elif dataset[mid] > find_num:
	    print('数字在%s范围内' % dataset[0:mid])
	    return datacheck(dataset[0:mid],find_num)
	else:
	    print('数字在%s范围内' % dataset[mid:len(dataset)-1])
	    return datacheck(dataset[mid:len(dataset)-1],find_num)
	else:
	    if dataset[0] == find_num:
	        print('找到数字了')
	    else:
		print('没有其他的了')

datacheck(data,6)
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]

def data_search(data,find_num,start=0,stop=len(data)-1):
    if start <= stop:
	mid = (start+(stop-start))//2
        if find_num > data[mid]:
            start = mid+1
        elif find_num < data[mid]:
	    stop = mid-1
        else:
            print('数字找到了-->>%s' % data[mid])
	    return data[mid]
        return data_search(data,find_num,start,stop)
    else:
	print('没有了')

data_search(data,7)

十一,匿名函数-->>lambda关键字

def func(x,y,z=1): #正常定义的函数
    return x+y+z
#匿名函数
lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
func=lambda x,y,z=1:x+y+z 
func(1,2,3)

#让其有名字就没有意义

name = 'alex'
def change_name(x):
	return name+'_sb'
res = change_name(name)
print(res)

f = lambda x:name+'_sb'
print(f(name))

func = lambda x:x+'_sb'
res = func(name)
print(res)
---------------------------------------------------
#lambda不会去单独使用
#func = lambda x,y,z:x+y+z
#print(func(1,2,3))

name1 = 'alex'
name2 = 'sbalex'
name3 = 'superalex'
f = lambda x,y,z:(x+1,y+1,z+1)
print(f(1,1,1))
---------------------------------------------------
#与其他函数搭配使用
l=[3,2,100,999,213,1111,31121,333]
print(max(l))
dic={'k1':10,'k2':100,'k3':30}

print(max(dic))
print(dic[max(dic,key=lambda k:dic[k])])
------------------------
res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
    print(i)

输出
1
25
49
16
64

十二,内置函数

>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

1.map() -->>处理序列中的每个元素,得到的结果是一个列表,该列表的元素个数与原来一样

#正常实现
num_1 = [1,2,3,4]
ret = []
for i in num_1:
    ret.append(i**2)
print(ret)

#将这个过程封装成一个函数
num_1 = [1,2,3,4]
def map_test(array):
    ret = []
    for i in array:
	ret.append(i**2)
    return ret
res = map_test(num_1)
print(res)

#将想要的方法列入函数的参数,如需实现该种方法,直接将方法对应的函数作为参数传入即可
num_1 = [1,2,3,4]
def add_one(x):
    return x+1
def remove_one(x):
    return x-1
def pf(x):
    return x**2
def map_test(func,array):
    ret = []
    for i in array:
        ret.append(func(i))
    return ret
print(map_test(remove_one,num_1))
print(map_test(add_one,num_1))
print(map_test(pf,num_1))

#当然也可以使用lambda关键字
num_1 = [1,2,3,4]
def map_test(func,array):
    ret = []
    for i in array:
        ret.append(func(i))
    return ret
print(map_test(lambda x:x-1,num_1))
print(map_test(lambda x:x+1,num_1))
print(map_test(lambda x:x**2,num_1))

#使用map()内置函数
num_1 = [1,2,3,4]
def map_test(func,array):
    ret = []
    for i in array:
        ret.append(func(i))
    return ret
res = map_test(lambda x:x+1,num_1)
print(res)
rea = map(lambda x:x+1,num_1)  #map()第二个参数为可迭代对象,map()的结果是可迭代对象
print(rea)
for i in rea:
    print(i)
print(list(rea))

2.filter() -->>遍历序列中的每个元素,判断每个元素的布尔值,如果是True则留下来

#将这个过程封装成一个函数
shuai_ge = ['sb_ji','sb_lao','sb_you','sb_wang','huang']
def filter_test(array):
    ret = []
    for each in array:
        if not each.startswith('sb'):
	    ret.append(each)
    return ret

print(filter_test(shuai_ge))

#将想要的方法列入函数的参数,如需实现该种方法,直接将方法对应的函数作为参数传入即可
shuai_ge = ['sb_ji_he','sb_lao_he','sb_you_he','sb_wang_he','huang']
def sb_show1(x):
    return x.endswith('he')
def sb_show2(x):
    return x.startswith('sb')
def filter_test(func,array):
    ret = []
    for each in array:
        if not func(each):
	    ret.append(each)
    return ret

print(filter_test(sb_show1,shuai_ge))
print(filter_test(sb_show2,shuai_ge))

#当然也可以使用lambda关键字
shuai_ge = ['sb_ji_he','sb_lao_he','sb_you_he','sb_wang_he','huang']
def filter_test(func,array):
    ret = []
    for each in array:
        if not func(each):
	    ret.append(each)
    return ret

print(filter_test(lambda x:x.startswith('sb'),shuai_ge))
print(filter_test(lambda x:x.endswith('he'),shuai_ge))

#使用filter()内置函数
shuai_ge = ['sb_ji_he','sb_lao_he','sb_you_he','sb_wang_he','huang']
def filter_test(func,array):
    ret = []
    for each in array:
        if not func(each):
	    ret.append(each)
    return ret

print(filter_test(lambda x:x.startswith('sb'),shuai_ge))
#map()第二个参数为可迭代对象,map()的结果是可迭代对象
res = filter(lambda x:not x.startswith('sb'),shuai_ge)
print(res)
for i in res:
    print(i)
print(list(res))

3.reduce()

其语法格式: reduce ( func , seq [ , init ] )

reduce函数过程:每次迭代,将上一次的迭代结果(第一次时为init的元素,如没有init则为seq的第一个元素)与下一个元素一同执行一个二元的func函数。在reduce函数中,init是可选的,如果使用,则作为第一次迭代的第一个元素使用。

#正常实现
num_1 = [1,2,3,100]
res = 0
for num in num_1:
    res += num
print(res)

#将这个过程封装成一个函数
num_1 = [1,2,3,100]
def reduce_test(array):
    res = 0
    for num in array:
        res += num
    return res
print(reduce_test(num_1))

#将一个功能函数作为参数传入
num_1 = [1,2,3,100]
def multi(x,y):
    return x*y
def reduce_test(func,array):
    res = array.pop(0)
    for num in array:
	res= func(res,num)
    return res
print(reduce_test(multi,num_1))

#增加init初始值
num_1 = [1,2,3,100]
def multi(x,y):
    return x*y
#lambda x,y:x*y
def reduce_test(func,array,init=None):#增加一个初始值参数
    if init is None:
        res = array.pop(0)
    else:
        res = init
	for num in array:
            res= func(res,num)
	return res

print(reduce_test(multi,num_1,100))
print(reduce_test(lambda x,y:x*y,num_1,100))

#reduce()函数
from functools import reduce
num_1 = [1,2,3,100]
print(reduce(lambda x,y:x+y,num_1,1))
print(reduce(lambda x,y:x+y,num_1))
print(reduce(lambda x,y:x*y,num_1,100))
print(reduce(lambda x,y:x*y,num_1))

总结:

#当然了,map,filter,reduce,可以处理所有数据类型

name_dic=[
    {'name':'alex','age':1000},
    {'name':'wupeiqi','age':10000},
    {'name':'yuanhao','age':9000},
    {'name':'linhaifeng','age':18},
]
#利用filter过滤掉千年王八,万年龟,还有一个九千岁
def func(x):
    age_list=[1000,10000,9000]
    return x['age'] not in age_list

res=filter(func,name_dic)
for i in res:
    print(i)

res=filter(lambda x:x['age'] == 18,name_dic)
for i in res:
    print(i)

#reduce用来计算1到100的和
from functools import reduce
print(reduce(lambda x,y:x+y,range(100),100))
print(reduce(lambda x,y:x+y,range(1,101)))

#用map来处理字符串列表啊,把列表中所有人都变成sb,比方alex_sb
name=['alex','laowang','jiba']
res=map(lambda x:x+'_sb',name)
for i in res:
    print(i)

其他内置函数

#abs -->>绝对值
print(abs(-1))
print(abs(1))
#all -->>将可迭代对象的每个元素逐一判断,如果都不为空或0,结果为布尔值True,反之为False,若迭代对象为空,也返回True
print(all([1,2,'1']))
print(all((1,2,'1')))
print(all([1,2,0]))
print(all(['hello']))
print(all(''))
print(all([]))
#any -->>与all相反,只要有一个元素不为0就返回True
print(any([0,'']))
print(any((0,'',1)))
print(any([0,'',1]))
#bin -->>将十进制改为二进制
print(bin(3))
#bool() -->>空,None,0的布尔值为False,其余的都为True
print(bool(''))
print(bool(None))
print(bool(0))
print(bool(1))
#bytes -->>将字符串转换成字节形式  注意编码与解码的格式要一样
name = '你好'
print(bytes(name,encoding='utf-8'))
print(bytes(name,encoding='utf-8').decode())

print(bytes(name,encoding='gbk'))
#print(bytes(name,encoding='gbk').decode())  -->>python3默认解码格式为utf-8,报错
print(bytes(name,encoding='gbk').decode('gbk'))
#chr -->>按照ascii表来转化
print(chr(97))
print(chr(45))
#divmod -->>计算两者相除,结果为商和余数
print(divmod(10,2))
print(divmod(10,3))
#eval 
#1.去掉字符串引号,将数据结构提取出来
#2.计算字符串中的表达式的值
name = '{"name":"huang"}'
a = eval(name)
print(a)
print(a['name'])

ex = '1+2*2'
b = eval(ex)
print(b)
#可hash的数据类型为不可变数据类型,不可hash的数据类型即可变数据类型
#hash() 进行哈希计算,得到一个哈希值,不论参数多长,得到的哈希值的长度是固定的
#只要参数变量不变,得到的哈希值是固定的,不能根据哈希值推导到原变量值
name = 'alex'
print(hash(name))
name ='Tom'
print(hash(name))
#hex -->>十进制转换成十六进制
print(bin(10)) #-->>10进制->2进制
print(hex(12)) #-->>10进制->16进制
print(oct(12)) #-->>10进制->8进制

max()&min()&sorted()

#字典的运算:最大值,最小值,排序
salaries={
    'egon':3000,
    'alex':100000000,
    'wupeiqi':10000,
    'yuanhao':2000
}

#迭代字典,取得的是key,因此比较key的最大值和最小值
res = max(salaries)
print(res)
res = min(salaries)
print(res)
#取values来比较
res = max(salaries.values())
print(res)
res = min(salaries.values())
print(res)
#想办法去除工资最高的人名,即比较值,得到键
res = max(salaries,key=lambda k:salaries[k])
print(res)
res = min(salaries,key=lambda k:salaries[k])
print(res)
#也可以通过zip实现
salaries_and_names = zip(salaries.values(),salaries.keys())

res = max(salaries_and_names)
print(res)

#salaries_and_names是迭代器,因此只能访问一次,因此min()出错
res = min(salaries_and_names)
print(res)

#sorted实现排序
l1 = [1,5,82,4,15,60]
res = sorted(l1,key=None,reverse=False)
print(res)
print(l1)
#将reverse值改为Ture,实现排序加翻转
l2 = [1,5,82,4,15,60]
res = sorted(l2,key=None,reverse=True)
print(res)
print(l2)

作业题:

写函数,计算传入字符串中数字、字母、空格 以及 其他的个数

def modify_file(filename,old,new):
    import os
    with open(filename,'r',encoding='utf-8') as read_f,\
        open('filename','w',encoding='utf-8') as write_f:
        for line in read_f:
            if old in line:
                line=line.replace(old,new)
            write_f.write(line)
    os.remove(filename)
    os.rename('.bak.swap',filename)

modify_file('1234.txt','value','key')

写函数,计算传入字符串中【数字】、【字母】、【空格】以及 【其他】的个数

def check_data(msg):
	data = {
		'数字':0,
		'字母':0,
		'空格':0,
		'其他':0
	}

	for i in msg:
		if i.isdigit():
			data['数字'] += 1
		elif i.isalpha():
			data['字母'] += 1
		elif i.isspace():
			data['空格'] += 1
		else:
			data['其他'] += 1
	return data
res = check_data('sfsfsfsfs1221213')
print(res)


写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。

def check_length(data):
	length = len(data)
	if len(data) > 5:
		print('%s长度大于5' % type(data))
	else:
		print('你的长度不足哦')

check_length('afafafasfaf')


写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。

def check_length(l):
	length = len(l)
	if length > 2:
		l = l[0:2]
	return l

res = check_length([1,2,3,4,5])
print(res)


写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
第一种
def check_lset(data):
	length = len(data)
	ls = []
	for i in range(length+1):
		if not i%2 == 0:
			ls.append(data[i])
	return ls
res = check_lset([1,5,6,7,9,1,5,8])
print(res)
第二种
def func2(seq):
    return seq[::2]
print(func2([1,2,3,4,5,6,7]))

写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
PS:字典中的value只能是字符串或列表

dic = {"k1":"v1v1", "k2":[11,22,33,44],"k3":(1,2)}

def func1(seq):
	dv = {}
	for k,v in seq.items():
		if len(v) > 2:
			dv[k] = v[0:2]
	return dv
res = func1(dic)
print(dic)
#用map来处理字符串列表啊,把列表中所有人都变成sb,比方alex_sb
name=['alex','heheda','liuliuda']

#用map来处理下述l,然后用list得到一个新的列表,列表中每个人的名字都是sb结尾
>>> l=[{'name':'alex'},{'name':'y'}]
>>> x=map(lambda i:{'name':i['name']+'sb'},l)
>>> for i in x:
...  print(i)
...
{'name': 'alexsb'}
{'name': 'ysb'}

#用filter来处理,得到股票价格大于20的股票名字
shares={
    'IBM':36.6,
    'Lenovo':23.2,
    'oldboy':21.2,
    'ocean':10.2,
}
>>> f=filter(lambda k:shares[k]>20,shares)
>>> list(f)
['IBM', 'Lenovo', 'oldboy']

#如下,每个小字典的name对应股票名字,shares对应多少股,price对应股票的价格
l = [
    {'name': 'IBM', 'shares': 100, 'price': 91.1},
    {'name': 'AAPL', 'shares': 50, 'price': 543.22},
    {'name': 'FB', 'shares': 200, 'price': 21.09},
    {'name': 'HPQ', 'shares': 35, 'price': 31.75},
    {'name': 'YHOO', 'shares': 45, 'price': 16.35},
    {'name': 'ACME', 'shares': 75, 'price': 115.65}
]

1:map来得出一个包含数字的迭代器,数字指的是:购买每支股票的总价格
>>> m=map(lambda item:item['shares']*item['price'],l)

2:基于1的结果,用reduce来计算,购买这些股票总共花了多少钱
>>> r=reduce(lambda x,y:x+y,m)
>>> r
51009.75

3:用filter过滤出,单价大于100的股票有哪些
>>> f=filter(lambda item:item['price'] > 100,l)

1、文件内容如下,标题为:姓名,性别,年纪,薪资

egon male 18 3000
alex male 38 30000
wupeiqi female 28 20000
yuanhao female 28 10000

要求:
从文件中取出每一条记录放入列表中,
列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式

2 根据1得到的列表,取出薪资最高的人的信息
3 根据1得到的列表,取出最年轻的人的信息
4 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式
5 根据1得到的列表,过滤掉名字以a开头的人的信息
6 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值


#1
with open('123.txt','r',encoding='utf-8') as f:
    items = (line.split() for line in f)
    print(items)
    info = [{'name':name,'sex':sex,'age':age,'salary':salary} \
	    for name,sex,age,salary in items]
print(info)
#2
print(max(info,key=lambda dic:dic['salary']))
#3
print(min(info,key=lambda dic:dic['age']))
#4
info_new1 = map(lambda item:{'name':item['name'].capitalize(),
			    'sex':item['sex'],
			    'age':item['age'],
		            'salary':item['salary']},info)
print(list(info_new1))
#5
info_new2 = filter(lambda item:item['name'].startswith('a'),info)
print(list(info_new2))
#6
l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]]

def get_all(l):
    for i in l:
        if type(i) == int:
	    print(i)
	else:
	    return get_all(i)
res = get_all(l)
print(res)



猜你喜欢

转载自blog.csdn.net/Mr_HUMI/article/details/80933750
今日推荐