Python基础—内置函数和匿名函数

 一、前引

我们之前学过函数的知识,知道函数的调用方式:

函数名()

然后函数在调用之前需要定义,定以后我们就可以使用了,但是有没有发现有些恨特别呢?

比如说print(),我们用的很频繁的一个函数,打印内容,我们再使用这个函数的时候,好像我们也没有定义这个函数啊,为什么就能直接拿来用了呢?

诸如此类的函数还有很多,如len()、input()等等

其实这些函数就是python中的内置函数,python环境中已经为我们定义好的一些完成特定功能的函数,在python环境的任何地方我们可以直接调用。

那这些内置函数到底有多少个呢?今天就来数一数.

二、内置函数

接下来,我们就一起来看看python里的内置函数。截止到python版本3.6.2,现在python一共为我们提供了68个内置函数。它们就是python提供给你直接可以拿来使用的所有函数。这些函数有些我们已经用过了,有些我们还没用到过,还有一些是被封印了,必须等我们学了新知识才能解开封印的。那今天我们就一起来认识一下python的内置函数。这么多函数,我们该从何学起呢?

上面就是内置函数的表格,68个内置函数堵在这里,下面我们按照功能的类别归类成以下6大类,依次来学习。

1.作用域相关

基于字典的方式获取局部变量和全局变量

globals(): 全局变量的字典

locals(): 获取执行本方法所在命名空间内的局部变量的字典

locals(): 打印局部变量,以字典形式返回,可以使用get方法

vars(): 如果没有参数,和locals()一样,返回本地变量名和值,放在字典中,如果有参数,则是查看某一个对象的所有方法,放在字典里面。

2.其他

字符串类型代码的执行

eval():将字符串类型的代码去掉引号并执行,不推荐使用

exec():将字符串类型的代码去掉引号后并执行,eval升级版,不推荐使用

code = '''
import os 
print(os.path.abspath('.'))
'''
code = '''
print(123)
a = 20
print(a)
'''
a = 10
exec(code,{'print':print},)
print(a)
指定global参数

compile:将字符串类型的代码编译。代码对象能够通过exec语句来执行或者eval()进行求值。

  参数说明   

  1. 参数source:字符串或者AST(Abstract Syntax Trees)对象。即需要动态执行的代码段。  

  2. 参数 filename:代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。当传入了source参数时,filename参数传入空字符即可。  

  3. 参数model:指定编译代码的种类,可以指定为 ‘exec’,’eval’,’single’。当source中包含流程语句时,model应指定为‘exec’;当source中只包含一个简单的求值表达式,model应指定为‘eval’;当source中包含了交互式命令语句,model应指定为'single'。

>>> #流程语句使用exec
>>> code1 = 'for i in range(0,10): print (i)'
>>> compile1 = compile(code1,'','exec')
>>> exec (compile1)
3
7


>>> #简单求值表达式用eval
>>> code2 = '1 + 2 + 3 + 4'
>>> compile2 = compile(code2,'','eval')
>>> eval(compile2)


>>> #交互语句用single
>>> code3 = 'name = input("please input your name:")'
>>> compile3 = compile(code3,'','single')
>>> name #执行前name变量不存在
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    name
NameError: name 'name' is not defined
>>> exec(compile3) #执行时显示交互命令,提示输入
please input your name:'pythoner'
>>> name #执行后name变量有值
"'pythoner'"
compile使用

输入输出相关

input():获取用户输入

print():打印输出

def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
    """
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    file:  默认是输出到屏幕,如果设置为文件句柄,输出到文件
    sep:   打印多个值之间的分隔符,默认为空格
    end:   每一次打印的结尾,默认为换行符
    flush: 立即把内容输出到流文件,不作缓存
    """

print源码剖析
print源码剖析
import time
for i in range(0,101,2):  
     time.sleep(0.1)
     char_num = i//2      #打印多少个'*'
     per_str = '\r%s%% : %s\n' % (i, '*' * char_num) if i == 100 else '\r%s%% : %s'%(i,'*'*char_num)
     print(per_str,end='', flush=True)
#小越越  : \r 可以把光标移动到行首但不换行

打印进度条
打印进度条

数据类型相关:

type(a):返回变量a的数据类型

内存相关:

id(a):返回参数a的内存地址

hash(a):a是参数,返回一个可hash变量的哈希值,不可hash的变量会报错

  hash函数会根据一个内部的算法对当前可hash变量进行处理,返回一个int数字。

  *每一次执行程序,内容相同的变量hash值在这一次执行过程中不会发生改变。

t = (1,2,3)
l = [1,2,3]
print(hash(t))  #可hash
print(hash(l))  #会报错

'''
结果:
TypeError: unhashable type: 'list'
'''

hash实例
hash实例

文件操作相关

open():打开一个文件,返回一个文件操作符(文件句柄)

模块操作相关

__import__:导入一个模块

# 第一种直接导入
import time

# 第二种导入字符串名字
os = __import__('os')
print(os.path.abspath('.'))

# 实际是通过sys模块找到'os'文件的路径,再导入使用

help(): 在控制台执行help()进入帮助模式,查看任意变量或者变量类型的有关操作

调用相关

callable(a): a是参数,查看这个参数是否可调用

如果a是一个函数名,则返回True

def func():pass
print(callable(func))  #参数是函数名,可调用,返回True
print(callable(123))   #参数是数字,不可调用,返回False

dir(): 默认查看全局空间内的属性,也可以接受一个参数查看这个参数内的方法或变量

print(dir(list))  #查看列表的内置方法
print(dir(int))  #查看整数的内置方法
查看内置方法

3.数字相关

数字——数据类型相关:bool, int, float, complex

数字——进制转换:bin, oct, hex

数字——数学运算:abs, divmod, min, max, sum, round, pow

min和max高级用法

'''
max比较字典类型的大小
'''

l = [1, 3, 100, -1, 2]

print(max(l))
dic = {'age1': 18, 'age2': 12}
print(max(dic))  # 比较的是字典的key
print(max(dic.values())) # 比较的是字典的值,但是不是对应那个键

# 结合zip函数比较
print(max(zip(dic.values(), dic.keys()))) # 比较字典的值,并显示对应的键
max比较字典大小
'''
最终的使用方法。
'''

people = [
    {'name': 'alex', 'age': 1000},
    {'name': 'wupeiqi', 'age': 10000},
    {'name': 'alex', 'age': 9000},
    {'name': 'alex', 'age': 18},
]

print(max(people, key=lambda dic:dic['age']))
# max()对可迭代对象的每一个元素比较,key接收元素的获取函数(匿名函数)

# min()和max()一样。
高级用法

4.数据结构相关

序列——列表与元组相关:强转类型:list和tuple

序列——字符串相关:str, format, bytes, bytearray, memoryview, ord, chr, ascii, repr

  format(str,格式化范式):格式化函数,

# format('a','>10')  # 格式化字符a的输出
# format(12,'08b')
格式化字符串

  bytes():将字符根据编码方式转化成对应编码方式的字节

  bytes():将字符根据编码方式转化成对应编码方式的字节

  chr():返回数字序号在Ascii中对应的字符,65-->A, 97-->a, 122-->z

  ord():返回字符在Ascii中对应的数字序号

  ascii():判断内容是否ascii字符集中,在的话返回,不在返回\u....一堆数字

  repr():显示的原本的数据,没有任何处理

ret = bytearray('alex',encoding='utf-8')
print(id(ret))
print(ret[0])
ret[0] = 65
print(ret)
print(id(ret))
bytearray
ret = memoryview(bytes('你好',encoding='utf-8'))
print(len(ret))
print(bytes(ret[:3]).decode('utf-8'))
print(bytes(ret[3:]).decode('utf-8'))
memoryview

数据集合——字典和集合:dict, set, frozenset

数据集合:

len(): 计算可迭代类型的长度

enumerate(iter[,x]): 枚举,遍历可迭代对象,返回每个对象并为其加上序号,x为序号起始数,默认为0

li = [1,2,3,4]
for index,element in (li,0):
    print(index,element)

all(): 判断可迭代类型中的所有元素是否都为真,是返回True,任意为假返回false

any(): 判断可迭代类型中元素是否有一个为真,是返回True,全为假返回false

zip(拉链):跟拉链一样,将两个可迭代类型中的元素一一对应,包裹在元组里,放在列表中

print(list(zip(('q', 'b', 'c'), (1, 2, 3)))) # [('q', 1), ('b', 2), ('c', 3)]
print(list(zip(('abcd'), ('123')))) # [('a', '1'), ('b', '2'), ('c', '3')]
# 可以拼接多个可迭代对象。不止两个
zip用法

slice(): 切片

l = 'hello'
s1 = slice(3, 5)  # l[s1] = l[3, 5]
s2 = slice(1, 4, 2)  # l[s2] = l[1, 4, 2]

print(l[s1])
print(l[s2])
slice用法

sorted方法

  给列表排序的两个方法(前提,列表中元素可比较)

    方法1.用List的成员函数sort进行排序,在本地进行排序,不返回副本
    方法2.用built-in函数sorted进行排序(从2.4开始),返回副本,原始输入不变

参数说明:
  iterable:是可迭代类型;
  key:传入一个函数名,函数的参数是可迭代类型中的每一项,根据函数的返回值大小排序;
  reverse:排序规则. reverse = True  降序 或者 reverse = False 升序,有默认值。
  返回值:有序列表

people = [
    {'name': 'alex', 'age': 1000},
    {'name': 'wupeiqi', 'age': 10000},
    {'name': 'alex', 'age': 9000},
    {'name': 'alex', 'age': 18},
]

print(sorted(people, key=lambda dic:dic['age']))
sorted用法

5.匿名函数

匿名函数:为了解决功能简单的需求而设计的一句话函数

#这段代码
def calc(n):
    return n**n
print(calc(10))
 
#换成匿名函数
calc = lambda n:n**n
print(calc(10))

上面是我们对calc这个匿名函数的分析,下面给出了一个关于匿名函数格式的说明

函数名 = lambda 参数 :返回值

#参数可以有多个,用逗号隔开
#匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
#返回值和正常的函数一样可以是任意数据类型

我们可以看出,匿名函数并不是真的不能有名字。

匿名函数的调用和正常的调用也没有什么分别。

除此之外,匿名函数也不是浪得虚名,它真的可以匿名。在和其他功能函数合作的时候

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])])
匿名函数应用

6.map、filter、reduce函数的用法

map(func, iter)

 映射函数:

  创建一个迭代器,使用可迭代对象的每个参数计算函数并返回。当最短的可迭代用尽时停止。

  map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

注:map函数内部会的机制会自动遍历传进来的可迭代对象。然后对遍历后的元素指定比较规则。(这里理解很重要)

num = [1, 2, 4, 5, 2, 8]
# 第一步需求,将列表中的数字全部平方

# new_li = []
# def square(array):
#     for i in array:
#         new_li.append(i**2)
#     return new_li
#
# print(square(num))


# 第二步需求,将列表中的数字全部减一
# new_li = []
# def reduce(array):
#     for i in array:
#         new_li.append(i-1)
#     return new_li
#
# print(reduce(num))

# 当需求过于巨大,需要一个一个实现,此时我们可以定义一个可以使用不同函数作用的函数


def square(num):
    return num**2


def reduce(num):
    return num - 1


def map_test(func, array):
    ret = []
    for i in array:
        res = func(i)
        ret.append(res)
    return ret

print(map_test(square, num))
print(map_test(reduce, num))
map函数的推导
# map函数使用
li = [1, 2, 3, 4, 5]
def square(num):
    return num**2

# 传入有名函数
map(square, li)

# 传入匿名函数
map(lambda x:x**2, li)

# 结果
[1, 4, 9, 16, 25]
map函数的使用

filter(func, iter): 过滤函数

  返回一个迭代器,产生函数(item)为true的iterable项。如果function为None,则返回结果为true的项。

# 有个需求,需要过滤movie_people中sb的人

movie_people = ['sb_alex', 'wupeiqi_sb', 'linhaifeng', 'sb_yuanhao']


ret = []
for p in movie_people:
    if not p.startswith('sb'):
        ret.append(p)

print(ret) # # ['linhaifeng']


# 封装成函数,过滤元素
def filter_test(array):
    ret = []
    for p in array:
        if not p.startswith('sb'):
            ret.append(p)
    return ret

print(filter_test(movie_people)) # ['wupeiqi_sb', 'linhaifeng']


# 需求更改,去除以sb结尾
# 所以不能将逻辑写死
def sb_show(n):
    return n.endswith('sb')

def filter_test(func, array):
    ret = []
    for p in array:
        if not func(p):
            ret.append(p)
    return ret

res = filter_test(sb_show, movie_people)
print(res) # ['sb_alex', 'linhaifeng', 'sb_yuanhao']


res = filter_test(lambda n:n.endswith('sb'), movie_people)
print(res) # ['sb_alex', 'linhaifeng', 'sb_yuanhao']
filter函数推导过程
# 请利用filter()过滤出1~100中平方根是整数的数,即结果应该是:
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

import math

def is_sqr(x):
    return math.sqrt(x) % 1 == 0
print(list(filter(is_sqr, range(1, 101))))

匿名函数写法:
print(list(filter(lambda x:math.sqrt(x)%1==0,range(1,101))))

reduce(func, iter)

 返回一个结果,将连个参数的函数累积到序列的项上,从做到右,以便将序列减少到单个值

  - 为了快速的进行累加,连乘的计算,使代码更简洁

  from functools import reduce

# reduce的推导过程

numbers = [1, 2, 3, 100]

# 需求1,将列表中元素累乘
res = 1
for num in numbers:
    res *= num
print(res)


# 需求2,封装成函数
def reduce_test(array):
    res = 1
    for num in array:
        res *= num
    return res

print(reduce_test(numbers))


# 需求3,要求功能可变,并置顶初始参数
def multi(x, y):
    return x*y
# 等价于
lambda x,y:x*y

def reduce_test(func, numbers, init=None):
    if init is None:
        res = 1
    else:
        res = init
    for num in numbers:
        res = func(res, num)
    return res

print(reduce_test(lambda x,y:x*y, numbers, 10))
reduce推导过程
# reduce的使用

from functools import reduce

li = [1,2,3,4,5]

print(reduce(lambda x,y:x*10+y, li))

'''
过程:
x=1,y=2 
>>> x*10+y = 1*10+2 = 12, 并将12赋值给x,y取值3 
>>> x*10+y = 12*10+3 = 123, 并将123赋值给x,y取值4
依次下去,最后-->12345
'''
reduce的使用
posted @ 2019-03-22 09:26  ryxiong728  阅读(274)  评论(0编辑  收藏  举报