新手上路必学的Python函数基础知识,全在这里了(多段代码举例)

2024-03-12 04:36

本文主要是介绍新手上路必学的Python函数基础知识,全在这里了(多段代码举例),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

函数是Python中最重要、最基础的代码组织和代码复用方式。根据经验,如果你需要多次重复相同或类似的代码,就非常值得写一个可复用的函数。通过给一组Python语句一个函数名,形成的函数可以帮助你的代码更加可读。

函数声明时使用def关键字,返回时使用return关键字:

 
 
def my_function(x, y, z=1.5):  
if z > 1:  return z * (x + y)  
else:  return z / (x + y)

函数参数的主要限制是关键字参数必须跟在位置参数后(如果有的话)。你可以按照任意顺序指定关键字参数;这可以让你不必强行记住函数参数的顺序,而只需用参数名指定。

也可以使用关键字参数向位置参数传参。在前面的例子中,我们也可以这样写:

 
my_function(x=5, y=6, z=7)  
my_function(y=6, x=5, z=7)

在部分场景中,这样做有助于代码可读性

二、命名空间、作用域和本地函数

函数有两种连接变量的方式:全局、本地。在Python中另一种更贴切地描述变量作用域的名称是命名空间。在函数内部,任意变量都是默认分配到本地命名空间的。本地命名空间是在函数被调用时生成的,并立即由函数的参数填充。当函数执行结束后,本地命名空间就会被销毁(除了一些特殊情况)。考虑以下函数:

 
def func():  a = []  for i in range(5):  a.append(i)

当func()调用时,空的列表会被创建,五个元素被添加到列表,之后a会在函数退出时被销毁。假设我们像下面这样声明a:

 
a = []  
def func():  for i in range(5):  a.append(i)

在函数外部给变量赋值是可以的,但是那变量必须使用global关键字声明为全局变量:

 
In [168]: a = None  
In [169]: def bind_a_variable():  
.....:        global a  
.....:        a = []  
.....:        bind_a_variable()  
.....:  
In [170]: print(a)  
[]

我简单的讲下global关键字的用法。通常全局变量用来存储系统中的某些状态。如果你发现你大量使用了全局变量,可能表明你需要面向对象编程(使用类)

三、返回多个值

当我在使用Java和C++编程后第一次使用Python编程时,我最喜欢的特性就是使用简单语法就可以从函数中返回多个值。以下是代码:

 
def f():  
a = 5  
b = 6  
c = 7  
return a, b, c  
a, b, c = f()

在数据分析和其他科研应用,你可能会发现经常需要返回多个值。这里实质上是返回了一个对象,也就是元组,而元组之后又被拆包为多个结果变量。在前面的例子中,我们可以用下面的代码代替:

return_value = f()

在这个例子中,return_value是一个3个元素的元组。像之前那样一次返回多个值还有一种潜在的、更有吸引力的实现:

 
def f():  
a = 5  
b = 6  
c = 7  
return {'a' : a, 'b' : b, 'c' : c}  

具体用哪种技术取决于你需要做什么的事。

四、 函数是对象

由于Python的函数是对象,很多在其他语言中比较难的构造在Python中非常容易实现。假设我们正在做数据清洗,需要将一些变形应用到下列字符串列表中:

 
 
In [171]: states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda',  
.....: 'south carolina##', 'West virginia?']

任何处理过用户提交数据的人都对这样的数据感到凌乱。为了使这些数据整齐、可用于分析,有很多是事情需要去做:去除空格、移除标点符号、调整适当的大小写。一种方式是使用内建的字符串方法,结合标准库中的正则表达式模块re:

 
import re  
def clean_strings(strings):  result = []  for value in strings:  value = value.strip()  value = re.sub('[!#?]', '', value)  value = value.title()  result.append(value)  return result

结果如下:

 
In [173]: clean_strings(states)  
Out[173]:  
['Alabama',  
'Georgia',  
'Georgia',  
'Georgia',  
'Florida',  
'South Carolina',  
'West Virginia']

另一种会让你觉得有用的实现就是将特定的列表操作应用到某个字符串的集合上:

 
def remove_punctuation(value):  
return re.sub('[!#?]', '', value)  
clean_ops = [str.strip, remove_punctuation, str.title]  
def clean_strings(strings, ops):  result = []  for value in strings:  for function in ops:  value = function(value)  result.append(value)  return result

结果如下:

 
In [175]: clean_strings(states, clean_ops)  
Out[175]:  
['Alabama',  
'Georgia',  
'Georgia',  
'Georgia',  
'Florida',  
'South Carolina',  
'West Virginia']

像这种更为函数化的模式可以使你在更高层次上方便地修改字符串变换方法。clean_strings函数现在也具有更强的复用性、通用性。

你可以将函数作为一个参数传给其他的函数,比如内建的map函数,可以将一个函数应用到一个序列上:

 
In [176]: for x in map(remove_punctuation, states):  
.....:        print(x)  
Alabama  
Georgia  
Georgia  
georgia  
FlOrIda  
south carolina  
West virginia

五、匿名(Lambda)函数

Python支持所谓的匿名或lambda函数。匿名函数是一种通过单个语句生成函数的方式,其结果是返回值。匿名函数使用lambda关键字定义,该关键字仅表达“我们声明一个匿名函数”的意思:

 
def short_function(x):  return x * 2  
equiv_anon = lambda x: x * 2  

匿名函数在数据分析中非常方便,因为在很多案例中数据变形函数都可以作为函数的参数。匿名函数代码量小(也更为清晰),将它作为参数进行传值,比写一个完整的函数或者将匿名函数赋值给局部变量更好。举个例子,考虑下面的不佳示例:

 
def apply_to_list(some_list, f):  return [f(x) for x in some_list]  
ints = [4, 0, 1, 5, 6]  
apply_to_list(ints, lambda x: x * 2)

你也可以写成[x * 2 for x in ints] ,但是在这里我们能够简单地将一个自定义操作符传递给apply_to_list函数。

另一个例子,假设你想要根据字符串中不同字母的数量对一个字符串集合进行排序:

In [177]: strings = ['foo', 'card', 'bar', 'aaaa', 'abab']

这里我们可以将一个匿名函数传给列表的sort方法:

 
In [178]: strings.sort(key=lambda x: len(set(list(x))))  
In [179]: strings  
Out[179]: ['aaaa', 'foo', 'abab', 'bar', 'card']

和def关键字声明的函数不同,匿名函数对象自身并没有一个显式的__name__ 属性,这是lambda函数被称为匿名函数的一个原因。

六、柯里化:部分函数应用

柯里化是计算机科学术语(以数学家Haskell Curry命名),它表示通过部分参数应用的方式从已有的函数中衍生出新的函数。例如,假设我们有一个不重要的函数,其功能是将两个数加一起:

 
def add_numbers(x, y):  
return x + y

使用这个函数,我们可以衍生出一个只有一个变量的新函数,add_five,可以给参数加上5:

add_five = lambda y: add_numbers(5, y)

第二个参数对于函数add_numers就是柯里化了。这里并没有什么神奇的地方,我们真正做的事只是定义了一个新函数,这个新函数调用了已经存在的函数。内建的functools模块可以使用pratial函数简化这种处理:

 
from functools import partial  
add_five = partial(add_numbers, 5)

七、生成器

通过一致的方式遍历序列,例如列表中的对象或者文件中的一行行内容,这是Python的一个重要特性。这个特性是通过迭代器协议来实现的,迭代器协议是一种令对象可遍历的通用方式。例如,遍历一个字典,获得字典的键:

 
In [180]: some_dict = {'a': 1, 'b': 2, 'c': 3}  
In [181]: for key in some_dict:  
.....:        print(key)  
a   
b  
c  

当你写下for key in some_dict 的语句时,Python解释器首先尝试根据some_dict生成一个迭代器:

 
In [182]: dict_iterator = iter(some_dict)  
In [183]: dict_iterator  
Out[183]: <dict_keyiterator at 0x7fbbd5a9f908>

迭代器就是一种用于在上下文中(比如for循环)向Python解释器生成对象的对象。大部分以列表或列表型对象为参数的方法都可以接收任意的迭代器对象。包括内建方法比如min、max和sum,以及类型构造函数比如list和tuple:

 
In [184]: list(dict_iterator)  
Out[184]: ['a', 'b', 'c']

用迭代器构造新的可遍历对象是一种非常简洁的方式。普通函数执行并一次返回单个结果,而生成器则“惰性”地返回一个多结果序列,在每一个元素产生之后暂停,直到下一个请求。如需创建一个生成器,只需要在函数中将返回关键字return替换为yield关键字:

 
def squares(n=10):  
print('Generating squares from 1 to {0}'.format(n ** 2))  
for i in range(1, n + 1):  yield i ** 2  

当你实际调用生成器时,代码并不会立即执行:

 
In [186]: gen = squares()  
In [187]: gen  
Out[187]: <generator object squares at 0x7fbbd5ab4570>  

直到你请求生成器中的元素时,它才会执行它的代码:

 
In [188]: for x in gen:  
.....: print(x, end=' ')  
Generating squares from 1 to 100  
1 4 9 16 25 36 49 64 81 100  

1. 生成器表达式

生成器表达式来创建生成器更为简单。生成器表达式与列表、字典、集合的推导式很类似,创建一个生成器表达式,只需要将列表推导式的中括号替换为小括号即可:

 
def _make_gen():  
for x in range(100):  yield x ** 2  
gen = _make_gen()  

上面的代码与下面更为复杂的生成器是等价的:

 
def _make_gen():  
for x in range(100):  yield x ** 2  
gen = _make_gen()  

在很多情况下,生成器表达式可以作为函数参数用于替代列表推导式:

 
In [191]: sum(x ** 2 for x in range(100))  
Out[191]: 328350  
In [192]: dict((i, i **2) for i in range(5))  
Out[192]: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}  

2. itertools模块

标准库中的itertools模块是适用于大多数数据算法的生成器集合。例如,groupby可以根据任意的序列和一个函数,通过函数的返回值对序列中连续的元素进行分组,参见下面的例子:

 
In [193]: import itertools  
In [194]: first_letter = lambda x: x[0]  
In [195]: names = ['Alan', 'Adam', 'Wes', 'Will', 'Albert', 'Steven']  
In [196]: for letter, names in itertools.groupby(names, first_letter):  
.....:        print(letter, list(names)) # names是一个生成器  
A ['Alan', 'Adam']  
W ['Wes', 'Will']  
A ['Albert']  
S ['Steven']  

下表是一些我认为经常用到的itertools函数的列表。你可以通过查询Python官方文档来获得更多关于内建工具库的信息。

函数描述
combinations(iterable,  k)根据iterable参数中的所有元素生成一个包含所有可能K元组的序列,忽略元素的顺序,也不进行替代(需要替代请参考函数 combinations_with_replacement )
permutations(iterable,  k)根据itrable参数中的按顺序生成包含所有可能K元组的序列
groupby(iterable[,  keyfunc])根据每一个独一的Key生成 (key, sub-iterator) 元组
product(*iterables,  repeat=1)以元组的形式,根据输入的可遍历对象们生成笛卡尔积,与嵌套的for循环类似

八、错误和异常处理

优雅地处理Python的错误或异常是构建稳定程序的重要组成部分。在数据分析应用中,很多函数只能处理特定的输入。例如,Python的float函数可以将字符串转换为浮点数字,但是对不正确的输入会产生ValueError:

 
In [197]: float('1.2345')  
Out[197]: 1.2345  
In [198]: float('something')  
---------------------------------------------------------------------------  
ValueError Traceback (most recent call last)  
<ipython-input-198-439904410854> in <module>()  
----> 1 float('something')  
ValueError: could not convert string to float: 'something' 

假设我们想要在float函数运行失败时可以优雅地返回输入参数。我们可以通过将float函数写入一个try/except代码段来实现:

 
 
def attempt_float(x):  
try:  return float(x)  
except:  return x  

如果float(x)执行时抛出了异常,则代码段中的except部分代码将会被执行:

 
 
In [200]: attempt_float('1.2345')  
Out[200]: 1.2345  
In [201]: attempt_float('something')  
Out[201]: 'something  

你可能会注意到,除了ValueError,float函数还会抛出其他的异常:

 
 
In [202]: float((1, 2))  
---------------------------------------------------------------------------  
TypeError Traceback (most recent call last)  
<ipython-input-202-842079ebb635> in <module>()  
----> 1 float((1, 2))  
TypeError: float() argument must be a string or a number, not 'tuple'  

你可能只想处理ValueError,因为TypeError(输入的不是字符串或数值)可能表明你的程序中有个合乎语法的错误。为了实现这个目的,在except后面写下异常类型:

 
def attempt_float(x):  
try:  return float(x)  
except ValueError:  return x  

然后我们可以得到:

 
In [204]: attempt_float((1, 2))  
---------------------------------------------------------------------------  
TypeError Traceback (most recent call last)  
<ipython-input-204-9bdfd730cead> in <module>()  
----> 1 attempt_float((1, 2))  
<ipython-input-203-3e06b8379b6b> in attempt_float(x)  
1 def attempt_float(x):  
2 try:  
----> 3 return float(x)  
4 except ValueError:  
5 return x  
TypeError: float() argument must be a string or a number, not 'tuple'  

你可以通过将多个异常类型写成元组的方式同事捕获多个异常(小括号是必不可少的):

 
def attempt_float(x):  
try:  return float(x)  
except (TypeError, ValueError):  return x  

某些情况下,你可能想要处理一个异常,但是你希望一部分代码无论try代码块是否报错都要执行。为了实现这个目的,使用finally关键字:

 
f = open(path, 'w')  
try:  write_to_file(f)  
finally:  f.close()  

这样,我们可以让f在程序结束后总是关闭。类似的,你可以使用else来执行当try代码块成功执行时才会执行的代码:

 
f = open(path, 'w')  
try:  write_to_file(f)  
except:  print('Failed')  
else:  print('Succeeded')  
finally:  f.close()  

IPython中的异常

如果当你正在%run一个脚本或执行任何语句报错时,IPython将会默认打印出完整的调用堆栈跟踪(报错追溯),会将堆栈中每个错误点附近的几行上下文代码打印出:

 
In [10]: %run examples/ipython_bug.py  
---------------------------------------------------------------------------  
AssertionError Traceback (most recent call last)  
/home/wesm/code/pydata-book/examples/ipython_bug.py in <module>()  
13 throws_an_exception()  
14  
---> 15 calling_things()  
/home/wesm/code/pydata-book/examples/ipython_bug.py in calling_things()  
11 def calling_things():  
12 works_fine()  
---> 13 throws_an_exception()  
14  
15 calling_things()  
/home/wesm/code/pydata-book/examples/ipython_bug.py in throws_an_exception()  
7 a = 5  
8 b = 6  
----> 9 assert(a + b == 10)  
10  
11 def calling_things():  
AssertionError:  

比标准Python解释器提供更多额外的上下文是IPython的一大进步(标准Python解释器不提供任何额外的上下文)。你可以使用%xmode命令来控制上下文的数量,可以从Plain(普通)模式(与标准Python解释器一致)切换到Verbose(复杂)模式(可以显示函数的参数值以及更多有用信息)。

作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:开心螺蛳粉】自提!

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。在这里插入图片描述

在这里插入图片描述

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群:1150305204,里面有各种测试开发资料和技术可以一起交流哦。

这篇关于新手上路必学的Python函数基础知识,全在这里了(多段代码举例)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/800148

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

计组基础知识

操作系统的特征 并发共享虚拟异步 操作系统的功能 1、资源分配,资源回收硬件资源 CPU、内存、硬盘、I/O设备。2、为应⽤程序提供服务操作系统将硬件资源的操作封装起来,提供相对统⼀的接⼝(系统调⽤)供开发者调⽤。3、管理应⽤程序即控制进程的⽣命周期:进程开始时的环境配置和资源分配、进程结束后的资源回收、进程调度等。4、操作系统内核的功能(1)进程调度能⼒: 管理进程、线

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能