Python教程第4章 | 条件语句、循环语句和函数

简介: Python if条件语句,for循环语句、Python函数


image.gif 编辑

一、条件语句

1、什么是条件语句

Python 条件语句跟其他语言基本一致的,都是通过一条或多条语句的执行结果( True 或者 False )来决定执行的代码块。

Python 程序语言指定任何非 0 和非空(null)值为 True,0 或者 null 为 False。

执行的流程图如下:

image.gif 编辑

2、if 语句的基本形式

Python 中,if 语句的基本形式如下:

if 判断条件:

   执行语句……

else:

   执行语句……

Python 语言有着严格的缩进要求,需要注意缩进,不要少写了冒号 :

if 语句的判断条件可以用>(大于)、<(小于)、==(等于)、>=(大于等于)、<=(小于等于)来表示其关系。

例如:

results=59
if results>=60:
    print ('及格')
else :
    print ('不及格')

image.gif

输出的结果为:

不及格

上面也说到,非零数值、非空字符串、非空 list 等,判断为 True,否则为 False。因此也可以这样写:

num = 6
if num :
    print('Hello Python')

image.gif

输出的结果如下:

image.gif 编辑

可见,把结果打印出来了。

那如果我们把 num 改为空字符串呢?

image.gif 编辑

很明显,空字符串是为 False 的,不符合条件语句,因此不会执行到 print('Hello Python') 这段代码。

还有再啰嗦一点,提醒一下,在条件判断代码中的冒号 : 后、下一行内容是一定要缩进的。不缩进是会报错的。

image.gif 编辑

冒号和缩进是一种语法。它会帮助 Python 区分代码之间的层次,理解条件执行的逻辑及先后顺序。

3、if 语句多个判断条件的形式

有些时候,我们的判断语句不可能只有两个,有些时候需要多个,比如上面的例子中大于 60 的为及格,那我们还要判断大于 90 的为优秀,在 80 到 90 之间的良好呢?

这时候需要用到 if 语句多个判断条件,

用伪代码来表示:

if 判断条件1:

   执行语句1……

elif 判断条件2:

   执行语句2……

elif 判断条件3:

   执行语句3……

else:

   执行语句4……

实例:

results = 89
if results > 90:
    print('优秀')
elif results > 80:
    print('良好')
elif results > 60:
    print ('及格')
else :
    print ('不及格')

image.gif

输出的结果:

良好

4、if 语句多个条件同时判断

有时候我们会遇到多个条件的时候该怎么操作呢?

比如说要求 java 和 python 的考试成绩要大于 80 分的时候才算优秀,这时候该怎么做?

这时候我们可以结合 orand 来使用。

or (或)表示两个条件有一个成立时判断条件成功

and (与)表示只有两个条件同时成立的情况下,判断条件才成功。

例如:

java = 86
python = 68
if java > 80 and  python > 80:
    print('优秀')
else :
    print('不优秀')
if ( java >= 80  and java < 90 )  or ( python >= 80 and python < 90):
    print('良好')

image.gif

输出结果:

不优秀

良好

注意:if 有多个条件时可使用括号来区分判断的先后顺序,括号中的判断优先执行,此外 and 和 or 的优先级低于 >(大于)、<(小于)等判断符号,即大于和小于在没有括号的情况下会比与或要优先判断。

5、if 嵌套

if 嵌套是指什么呢?

就跟字面意思差不多,指 if 语句中可以嵌套 if 语句。

比如上面说到的例子,也可以用 if 嵌套来写。

image.gif 编辑

当然这只是为了说明 if 条件语句是可以嵌套的。如果是这个需求,我个人还是不太建议这样使用 if 嵌套的,因为这样代码量多了,而且嵌套太多,也不方便阅读代码。

二、循环语句

1、什么是循环语句

一般编程语言都有循环语句,为什么呢?

那就问一下自己,我们弄程序是为了干什么?

那肯定是为了方便我们工作,优化我们的工作效率啊。

而计算机和人类不同,计算机不怕苦也不怕累,也不需要休息,可以一直做。

你要知道,计算机最擅长就是做重复的事情。

所以这时候需要用到循环语句,循环语句允许我们执行一个语句或语句组多次。

循环语句的一般形式如下:

image.gif 编辑

在 Python 提供了 for 循环和 while 循环。

这里又有一个问题了,如果我想让他运行了一百次之后停止,那该怎么做呢?

这时候需要用到一些控制循环的语句:

循环控制语句 描述
break 在语句块执行过程中终止循环,并且跳出整个循环
continue 在语句块执行过程中终止当前循环,跳出该次循环,执行下一次循环
pass pass 是空语句,是为了保持程序结构的完整性

这些控制语句是为了让我们告诉程序什么时候停止,什么时候不运行这次循环。

2、 for 循环语句

我们先来看下 for 循环语句。

它的流程图基本如下:

image.gif 编辑

基本的语法格式:

for iterating_var in sequence:

  statements(s)

那么我们根据他的基本语法格式,随便写个例子测试一下:

for letter in 'Hello 程序员':
    print(letter)

image.gif

输出的结果如下:

H

e

l

l

o


从打印结果来看,它就是把字符串 Hello 程序员 一个一个字符的打印出来。

那如果我们把字符串换为字典 dict 呢?

image.gif 编辑

你会发现只打印了字典 dict 中的每一个 key 值。

很多时候,我都是建议大家学到一个新的知识点,都多去尝试。

你尝试一遍,自己观察出来的结论,好过别人说十遍。

如果你不知道怎么去试?

可以根据我们的例子举一反三,比如上面的 for 循环,试了字符串,字典,那我们之前学的基本数据类型还有什么呢?

不记得可以再返回去看看,可以把所有的基本类型都拿去尝试一下。

比如,你试了之后,会发现整数和浮点数是不可以直接放在 for 循环里面的。

image.gif 编辑

3、 range() 函数

for 循环还常常和 range() 函数搭配使用的。

如果不知道 range() 函数 , 我们直接通过一段程序来理解。

for i in range(3):
    print(i)

image.gif

打印的结果为:

0
1
2

image.gif

可见,打印了 0 到 3 。

使用 range(x) 函数,就可以生成一个从 0 到 x-1 的整数序列。

如果是 range(a,b) 函数,你可以生成了一个左闭右开的整数序列。

其实例子中的 range(3) 可以写成 range(0,3), 结果是一样的。

其实使用 range() 函数,我们更多是为了把一段代码重复运行 n 次。

这里提个问题,你仔细观察 range() 函数,上面说到的不管是 1 个参数的,还是 2 个参数的都有什么共同的特点?

不知道你们有没有发现,他都是每次递增 1 的。

range(3) 就是 0 ,1,2 ,每次递增 1 。

range(3,6) 就是 3 ,4 ,5 ,也是每次递增 1 的。

那能不能每次不递增 1 呢?

比如我想递增 2 呢?

在程序的编写中,肯定会遇到这样的需求的。而 python 发展至今,range 函数肯定也会有这种功能。

所以 range 函数还有一个三个参数的。

比如 range(0,10,2) , 它的意思是:从 0 数到 10(不取 10 ),每次间隔为 2 。

image.gif 编辑

4、While 循环语句

While 循环和 for 循环的作用是一样的。

我们先来看看 While 循环语句的样子。

image.gif 编辑

程序输出的结果是:

5050

这个例子是计算 1 到 100 所有整数的和。

5、for 循环和 whlie 循环的区别

之前也提到过了,如果一种语法能表示一个功能,那没必要弄两种语法来表示。

竟然都是循环,for 循环和 while 循环肯定有他们的区别的。

那什么时候才使用 for 循环和 while 循环呢?

  • for 循环主要用在迭代可迭代对象的情况。
  • while 循环主要用在需要满足一定条件为真,反复执行的情况。 (死循环+break 退出等情况。)
  • 部分情况下,for 循环和 while 循环可以互换使用。

例如:

for i in range(0, 10):

   print(i)



i = 0

while i < 10:

   print(i)

   i = i + 1

虽然打印的结果是一样的,但是细细品味你会发现,他们执行的顺序和知道的条件是不同的。

6、嵌套循环

循环语句和条件语句一样,都是可以嵌套的。

具体的语法如下:

for 循环嵌套语法

for iterating_var in sequence:

  for iterating_var in sequence:

     statements(s)

  statements(s)

while 循环嵌套语法

while expression:

  while expression:

     statement(s)

  statement(s)

除此之外,你也可以在循环体内嵌入其他的循环体,如在 while 循环中可以嵌入 for 循环, 反之,你可以在 for 循环中嵌入 while 循环

比如:

当我们需要判断 sum 大于 1000 的时候,不在相加时,可以用到 break ,退出整个循环。

count = 1
sum = 0
while (count <= 100):
    sum = sum + count
    if ( sum > 1000):  #当 sum 大于 1000 的时候退出循环
        break
    count = count + 1
print(sum)

image.gif

输出的结果:

1035

有时候,我们只想统计 1 到 100 之间的奇数和,那么也就是说当 count 是偶数,也就是双数的时候,我们需要跳出当次的循环,不想加,这时候可以用到 break

count = 1
sum = 0
while (count <= 100):
    if ( count % 2 == 0):  # 双数时跳过输出
        count = count + 1
        continue
    sum = sum + count
    count = count + 1
print(sum)

image.gif

输出的语句:

2500

还有:

for num in range(10,20):  # 迭代 10 到 20 之间的数字
   for i in range(2,num): # 根据因子迭代
      if num%i == 0:      # 确定第一个因子
         j=num/i          # 计算第二个因子
         print ('%d 是一个合数' % num)
         break            # 跳出当前循环
   else:                  # 循环的 else 部分
      print ('%d 是一个质数' % num)

image.gif

输出的结果:

10 是一个合数

11 是一个质数

12 是一个合数

13 是一个质数

14 是一个合数

15 是一个合数

16 是一个合数

17 是一个质数

18 是一个合数

19 是一个质数

当然,这里还用到了 for … else 语句。

其实 for 循环中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行。

当然有 for … else ,也会有 while … else 。他们的意思都是一样的。

三、条件语句和循环语句综合实例

1、打印九九乘法表

# 打印九九乘法表
for i in range(1, 10):
        for j in range(1, i+1):
            # 打印语句中,大括号及其里面的字符 (称作格式化字段) 将会被 .format() 中的参数替换,注意有个点的
            print('{}x{}={}\t'.format(i, j, i*j), end='')  
        print()

image.gif

输出的结果:

1x1=1  

2x1=2   2x2=4  

3x1=3   3x2=6   3x3=9  

4x1=4   4x2=8   4x3=12  4x4=16  

5x1=5   5x2=10  5x3=15  5x4=20  5x5=25  

6x1=6   6x2=12  6x3=18  6x4=24  6x5=30  6x6=36  

7x1=7   7x2=14  7x3=21  7x4=28  7x5=35  7x6=42  7x7=49  

8x1=8   8x2=16  8x3=24  8x4=32  8x5=40  8x6=48  8x7=56  8x8=64  

9x1=9   9x2=18  9x3=27  9x4=36  9x5=45  9x6=54  9x7=63  9x8=72  9x9=81

2、判断是否是闰年

# 判断是否是闰年
year = int(input("请输入一个年份: "))
if (year % 4) == 0 and (year % 100) != 0 or (year % 400) == 0:
    print('{0} 是闰年' .format(year))
else:
     print('{0} 不是闰年' .format(year))

image.gif

函数

一、Python 自定义函数的基本步骤

1、什么是函数

函数,其实我们一开始学 Python 的时候就接触过。

不过我们使用的大多数都是 Python 的内置函数。

比如基本每个章节都会出现的 print() 函数。

而现在,我们主要学习的是自定义函数。

各位有没有想过为什么需要函数呢?

如果要想回答这个问题,我们需要先了解函数是什么?

函数就是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

没错,函数其实就是把代码抽象出来的代码段。

那为什么要抽象出来呢?

方便我们使用,方便我们重复使用。

函数的本质就是我们把一些数据喂给函数,让他内部消化,然后吐出你想要的东西,至于他怎么消化的,我们不需要知道,它内部解决。

怎么理解这句话呢?

举个例子,好比每次用到的 print 函数,我们都知道这个函数的作用是可以把我们的数据输出到控制台,让我们看到。所以 print('两点水') , 我们想打印 两点水 出来,就把 两点水 这个数据喂给 print 函数,然后他就直接把结果打印到控制台上了。

2、怎么自定义函数

怎么自定义函数?

要知道怎么定义函数,就要知道函数的组成部分是怎样的。

def 函数名(参数1,参数2....参数n):

   函数体

   return 语句

这就是 Python 函数的组成部分。

所以自定义函数,基本有以下规则步骤:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数
  • 函数的第一行语句可以选择性地使用文档字符串(用于存放函数说明)
  • 函数内容以冒号起始,并且缩进
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的 return 相当于返回 None。

语法示例:

def functionname( parameters ):

  "函数_文档字符串"

  function_suite

  return [expression]

实例:

  1. def 定义一个函数,给定一个函数名 sum
  2. 声明两个参数 num1 和 num2
  3. 函数的第一行语句进行函数说明:两数之和
  4. 最终 return 语句结束函数,并返回两数之和
def sum(num1,num2):
  "两数之和"
  return num1+num2
# 调用函数
print(sum(5,6))

image.gif

输出结果:

11

二、函数返回值

通过上面的学习,可以知道通过 return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。

不带参数值的 return 语句返回 None。

具体示例:

def sum(num1,num2):
  # 两数之和
  if not (isinstance (num1,(int ,float)) and isinstance (num2,(int ,float))):
    raise TypeError('参数类型错误')
  return num1+num2
print(sum(1,2))

image.gif

返回结果:

3

这个示例,还通过内置函数isinstance()进行数据类型检查,检查调用函数时参数是否是整形和浮点型。如果参数类型不对,会报错,提示 参数类型错误,如图:

image.gif 编辑

当然,函数也可以返回多个值,具体实例如下:

def  division ( num1, num2 ):
  # 求商与余数
         a = num1 % num2
         b = (num1-a) / num2
         return b , a
num1 , num2 = division(9,4)
tuple1 = division(9,4)
print (num1,num2)
print (tuple1)

image.gif

输出的值:

2.0 1

(2.0, 1)

认真观察就可以发现,尽管从第一个输出值来看,返回了多个值,实际上是先创建了一个元组然后返回的。

回忆一下,元组是可以直接用逗号来创建的,观察例子中的 ruturn ,可以发现实际上我们使用的是逗号来生成一个元组。

Python 语言中的函数返回值可以是多个,而其他语言都不行,这是Python 相比其他语言的简便和灵活之处。

Python 一次接受多个返回值的数据类型就是元组。

不知道此刻你还记不记得元组的相关知识,如果不记得,建议现在立刻写几个例子回忆一下,比如如何获取元组的第一个元素出来。

三、函数的参数

1、函数的参数类型

设置与传递参数是函数的重点,而 Python 的函数对参数的支持非常的灵活。

主要的参数类型有:默认参数、关键字参数(位置参数)、不定长参数。

下面我们将一一了解这几种参数。

2、默认参数

有时候,我们自定义的函数中,如果调用的时候没有设置参数,需要给个默认值,这时候就需要用到默认值参数了。

默认参数,只要在构造函数参数的时候,给参数赋值就可以了

例如:

def print_user_info( name , age , sex = '男' ):
    # 打印用户信息
    print('昵称:{}'.format(name) , end = ' ')
    print('年龄:{}'.format(age) , end = ' ')
    print('性别:{}'.format(sex))
    return;
# 调用 print_user_info 函数
print_user_info( '两点水' , 18 , '女')
print_user_info( '三点水' , 25 )

image.gif

输出结果:

昵称:两点水 年龄:18 性别:女

昵称:三点水 年龄:25 性别:男

从输出结果可以看到,当你设置了默认参数的时候,在调用函数的时候,不传该参数,就会使用默认值。

但是这里需要注意的一点是:只有在形参表末尾的那些参数可以有默认参数值,也就是说你不能在声明函数形参的时候,先声明有默认值的形参而后声明没有默认值的形参。

这是因为赋给形参的值是根据位置而赋值的。例如,def func(a, b=1) 是有效的,但是 def func(a=1, b) 是 无效 的。

默认值参数就这样结束了吗?

还没有的,细想一下,如果参数中是一个可修改的容器比如一个 lsit (列表)或者 dict (字典),那么我们使用什么来作为默认值呢?

我们可以使用 None 作为默认值。就像下面这个例子一样:

# 如果 b 是一个 list ,可以使用 None 作为默认值
def print_info( a , b = None ):
    if b is None :
        b=[]
    return;

image.gif

认真看下例子,会不会有这样的疑问呢?在参数中我们直接 b=[] 不就行了吗?

也就是写成下面这个样子:

对不对呢?

运行一下也没发现错误啊,可以这样写吗?

这里需要特别注意的一点:默认参数的值是不可变的对象,比如None、True、False、数字或字符串,如果你像上面的那样操作,当默认值在其他地方被修改后你将会遇到各种麻烦。

这些修改会影响到下次调用这个函数时的默认值。

示例如下:

def print_info( a , b = [] ):
    print(b)
    return b ;
result = print_info(1)
result.append('error')
print_info(2)

image.gif

输出的结果:

[]

['error']

认真观察,你会发现第二次输出的值根本不是你想要的,因此切忌不能这样操作。

还有一点,有时候我就是不想要默认值啊,只是想单单判断默认参数有没有值传递进来,那该怎么办?

我们可以这样做:

_no_value =object()
def print_info( a , b = _no_value ):
    if b is _no_value :
        print('b 没有赋值')
    return;

image.gif

这里的 object 是 python 中所有类的基类。 你可以创建 object 类的实例,但是这些实例没什么实际用处,因为它并没有任何有用的方法, 也没有任何实例数据(因为它没有任何的实例字典,你甚至都不能设置任何属性值)。 你唯一能做的就是测试同一性。也正好利用这个特性,来判断是否有值输入。

3、关键字参数(位置参数)

一般情况下,我们需要给函数传参的时候,是要按顺序来的,如果不对应顺序,就会传错值。

不过在 Python 中,可以通过参数名来给函数传递参数,而不用关心参数列表定义时的顺序,这被称之为关键字参数。

使用关键参数有两个优势 :

  • 由于我们不必担心参数的顺序,使用函数变得更加简单了。
  • 假设其他参数都有默认值,我们可以只给我们想要的那些参数赋值

具体看例子:

def print_user_info( name ,  age  , sex = '男' ):
    # 打印用户信息
    print('昵称:{}'.format(name) , end = ' ')
    print('年龄:{}'.format(age) , end = ' ')
    print('性别:{}'.format(sex))
    return;
# 调用 print_user_info 函数
print_user_info( name = '两点水' ,age = 18 , sex = '女')
print_user_info( name = '两点水' ,sex = '女', age = 18 )

image.gif

输出的值:

昵称:两点水 年龄:18 性别:女

昵称:两点水 年龄:18 性别:女

4、不定长参数

或许有些时候,我们在设计函数的时候,我们有时候无法确定传入的参数个数。

那么我们就可以使用不定长参数。

Python 提供了一种元组的方式来接受没有直接定义的参数。这种方式在参数前边加星号 *

如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。

例如:

def print_user_info( name ,  age  , sex = '男' , * hobby):
    # 打印用户信息
    print('昵称:{}'.format(name) , end = ' ')
    print('年龄:{}'.format(age) , end = ' ')
    print('性别:{}'.format(sex) ,end = ' ' )
    print('爱好:{}'.format(hobby))
    return;
# 调用 print_user_info 函数
print_user_info( '两点水' ,18 , '女', '打篮球','打羽毛球','跑步')

image.gif

输出的结果:

昵称:两点水 年龄:18 性别:女 爱好:('打篮球', '打羽毛球', '跑步')

通过输出的结果可以知道,*hobby是可变参数,且 hobby 其实就是一个 tuple (元祖)

可变长参数也支持关键字参数(位置参数),没有被定义的关键参数会被放到一个字典里。

这种方式即是在参数前边加 **,更改上面的示例如下:

def print_user_info( name ,  age  , sex = '男' , ** hobby ):
    # 打印用户信息
    print('昵称:{}'.format(name) , end = ' ')
    print('年龄:{}'.format(age) , end = ' ')
    print('性别:{}'.format(sex) ,end = ' ' )
    print('爱好:{}'.format(hobby))
    return;
# 调用 print_user_info 函数
print_user_info( name = '两点水' , age = 18 , sex = '女', hobby = ('打篮球','打羽毛球','跑步'))

image.gif

输出的结果:

昵称:两点水 年龄:18 性别:女 爱好:{'hobby': ('打篮球', '打羽毛球', '跑步')}

通过对比上面的例子和这个例子,可以知道,*hobby是可变参数,且 hobby其实就是一个 tuple (元祖),**hobby是关键字参数,且 hobby 就是一个 dict (字典)

5、只接受关键字参数

关键字参数使用起来简单,不容易参数出错,那么有些时候,我们定义的函数希望某些参数强制使用关键字参数传递,这时候该怎么办呢?

将强制关键字参数放到某个*参数或者单个*后面就能达到这种效果,比如:

def print_user_info( name , *, age  , sex = '男' ):
    # 打印用户信息
    print('昵称:{}'.format(name) , end = ' ')
    print('年龄:{}'.format(age) , end = ' ')
    print('性别:{}'.format(sex))
    return;
# 调用 print_user_info 函数
print_user_info( name = '两点水' ,age = 18 , sex = '女' )
# 这种写法会报错,因为 age ,sex 这两个参数强制使用关键字参数
#print_user_info( '两点水' , 18 , '女' )
print_user_info('两点水',age='22',sex='男')

image.gif

通过例子可以看,如果 age , sex 不使用关键字参数是会报错的。

很多情况下,使用强制关键字参数会比使用位置参数表意更加清晰,程序也更加具有可读性。使用强制关键字参数也会比使用 **kw 参数更好且强制关键字参数在一些更高级场合同样也很有用。

四、函数传值问题

先看一个例子:

def chagne_number( b ):
    b = 1000
b = 1
chagne_number(b)
print( b )

image.gif

最后输出的结果为:

1

先看看运行的结果?

想一下为什么打印的结果是 1 ,而不是 1000 ?

其实把问题归根结底就是,为什么通过函数 chagne_number 没有更改到 b 的值?

这个问题很多编程语言都会讲到,原理解释也是差不多的。

这里主要是函数参数的传递中,传递的是类型对象,之前也介绍了 Python 中基本的数据类型等。而这些类型对象可以分为可更改类型和不可更改的类型

在 Python 中,字符串,整形,浮点型,tuple 是不可更改的对象,而 list , dict 等是可以更改的对象。

例如:

不可更改的类型:变量赋值 a = 1,其实就是生成一个整形对象 1 ,然后变量 a 指向 1,当 a = 1000 其实就是再生成一个整形对象 1000,然后改变 a 的指向,不再指向整形对象 1 ,而是指向 1000,最后 1 会被丢弃

可更改的类型:变量赋值 a = [1,2,3,4,5,6] ,就是生成一个对象 list ,list 里面有 6 个元素,而变量 a 指向 list ,a[2] = 5则是将 list a 的第三个元素值更改,这里跟上面是不同的,并不是将 a 重新指向,而是直接修改 list 中的元素值。

image.gif 编辑

这也将影响到函数中参数的传递了:

不可更改的类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是 a 的值,没有影响 a 对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

可更改的类型:类似 c++ 的引用传递,如 列表,字典。如 fun(a),则是将 a 真正的传过去,修改后 fun 外部的 a 也会受影响

因此,在一开始的例子中,b = 1,创建了一个整形对象 1 ,变量 b 指向了这个对象,然后通过函数 chagne_number 时,按传值的方式复制了变量 b ,传递的只是 b 的值,并没有影响到 b 的本身。具体可以看下修改后的实例,通过打印的结果更好的理解。

def chagne_number( b ):
    print('函数中一开始 b 的值:{}' .format( b ) )
    b = 1000
    print('函数中 b 赋值后的值:{}' .format( b ) )
b = 1
chagne_number( b )
print( '最后输出 b 的值:{}' .format( b )  )

image.gif

打印的结果:

函数中一开始 b 的值:1

函数中 b 赋值后的值:1000

最后输出 b 的值:1

当然,如果参数中的是可更改的类型,那么调用了这个函数后,原来的值也会被更改,具体实例如下:

def chagne_list( b ):
    print('函数中一开始 b 的值:{}' .format( b ) )
    b.append(1000)
    print('函数中 b 赋值后的值:{}' .format( b ) )
b = [1,2,3,4,5]
chagne_list( b )
print( '最后输出 b 的值:{}' .format( b )  )

image.gif

输出的结果:

函数中一开始 b 的值:[1, 2, 3, 4, 5]

函数中 b 赋值后的值:[1, 2, 3, 4, 5, 1000]

最后输出 b 的值:[1, 2, 3, 4, 5, 1000]

五、匿名函数

有没有想过定义一个很短的回调函数,但又不想用 def 的形式去写一个那么长的函数,那么有没有快捷方式呢?

答案是有的。

python 使用 lambda 来创建匿名函数,也就是不再使用 def 语句这样标准的形式定义一个函数。

匿名函数主要有以下特点:

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。

基本语法

lambda [arg1 [,arg2,.....argn]]:expression

示例:

sum = lambda num1 , num2 : num1 + num2;
print( sum( 1 , 2 ) )

image.gif

输出的结果:

3

注意:尽管 lambda 表达式允许你定义简单函数,但是它的使用是有限制的。 你只能指定单个表达式,它的值就是最后的返回值。也就是说不能包含其他的语言特性了, 包括多个语句、条件表达式、迭代以及异常处理等等。

匿名函数中,有一个特别需要注意的问题,比如,把上面的例子改一下:

num2 = 100
sum1 = lambda num1 : num1 + num2 ;
num2 = 10000
sum2 = lambda num1 : num1 + num2 ;
print( sum1( 1 ) )
print( sum2( 1 ) )

image.gif

你会认为输出什么呢?第一个输出是 101,第二个是 10001,结果不是的,输出的结果是这样:

10001

10001

这主要在于 lambda 表达式中的 num2 是一个自由变量,在运行时绑定值,而不是定义时就绑定,这跟函数的默认值参数定义是不同的。所以建议还是遇到这种情况还是使用第一种解法。

下一章:Python第5章 | Python迭代器和生成器

相关文章
|
3天前
|
Python
SciPy 教程 之 Scipy 显著性检验 3
本教程介绍Scipy显著性检验,包括其基本概念、原理及应用。显著性检验用于判断样本与总体假设间的差异是否显著,是统计学中的重要工具。Scipy通过`scipy.stats`模块提供了相关功能,支持双边检验等方法。
10 1
|
5天前
|
机器学习/深度学习 Python
SciPy 教程 之 SciPy 插值 2
SciPy插值教程:介绍插值概念及其在数值分析中的应用,特别是在处理数据缺失时的插补和平滑数据集。SciPy的`scipy.interpolate`模块提供了强大的插值功能,如一维插值和样条插值。通过`UnivariateSpline()`函数,可以轻松实现单变量插值,示例代码展示了如何对非线性点进行插值计算。
10 3
|
6天前
|
机器学习/深度学习 数据处理 Python
SciPy 教程 之 SciPy 空间数据 7
本教程介绍了SciPy的空间数据处理功能,涵盖如何使用`scipy.spatial`模块进行点的位置判断、最近点计算等操作。还详细解释了距离矩阵的概念及其在生物信息学中的应用,以及汉明距离的定义和计算方法。示例代码展示了如何计算两个点之间的汉明距离。
12 1
|
4天前
|
机器学习/深度学习 数据处理 Python
SciPy 教程 之 SciPy 插值 3
本教程介绍了SciPy中的插值方法,包括什么是插值及其在数据处理和机器学习中的应用。通过 `scipy.interpolate` 模块,特别是 `Rbf()` 函数,展示了如何实现径向基函数插值,以平滑数据集中的离散点。示例代码演示了如何使用 `Rbf()` 函数进行插值计算。
8 0
|
4天前
|
Python
SciPy 教程 之 Scipy 显著性检验 1
本教程介绍Scipy显著性检验,包括统计假设、零假设和备择假设等概念,以及如何使用scipy.stats模块进行显著性检验,以判断样本与总体假设间是否存在显著差异。
8 0
|
程序员 Python
6_python基础—循环(上)
6_python基础—循环
105 0
6_python基础—循环(上)
7_python基础—while循环应用1-100累加和
7_python基础—while循环应用1-100累加和
380 0
|
Python
6_python基础—循环(下)
6_python基础—循环
119 0
|
Python
猪行天下之Python基础——4.1 条件判断与循环
内容简述: 1、条件判断 2、循环
85 0
|
机器学习/深度学习 Python
Python基础(条件判断和循环) if elif else for while break continue;
条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断。 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age >= 18: print('your age is', age) print('adult') 根据Python的缩进规则,如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么也不做。
2543 1