当前位置: 首页 > news >正文

5.条件,循环和其他语句

5.1print和import的更多特性。

5.1.1使用逗号输出

print可以通过逗号输出多个表达式。

 

5.1.2把某件事作为另一件事导入

四种import的方式:

1.import module

2.from module import function1

3.from module import function1, function2...

4 from module import *:import module中的所有function

假如import两个module有名字相同的函数,那么可以直接用第一种方法区分。用法是module1.function()和module2.function()

也可以通过as为整个模块或者函数提供别名:

1.为模块提供别名

2.为函数提供别名

 

5.2赋值

5.2.1并行赋值:序列解包(sequence unpacking)

一般的赋值都是一个值赋值给一个变量,例如a=1。并行赋值则是多个不同的值赋值给多个变量。它的过程相当于把左边的所有变量和右边所有的值当成序列(等号右边可以是序列),把右边的序列解开,再把其中的值赋值到左边的每个变量上。这个过程也被称为序列解包。因为它是将左边变量和右边的值一一对应的过程,所以左右两边的变量数和值的数量必须相等(没有‘*’号时,下面会具体讲),否则会报错。

当然也可以在右边的值两旁添加'[ ]'直接转为序列:

当函数返回序列是,序列解包很容易快速获得序列中想要的数据。

另外,在序列解包中有时可以运用‘*‘号。例子如下:

没有星号的,根据他们的相对位置会被赋一个值(a是第一个,赋值1,c是最后一个,赋值4,剩下的全赋值给b),剩下的值都将以列表的形式赋值给有星号的变量。每一次并行赋值中最多只能有一个有星号的变量。

 

5.2.2链式赋值(chained assignment)

链式赋值就是一个值赋值给多个变量。变量间用等号连接。

c='a'
b=c
a=b

效果一样。

 

5.2.3增量赋值

简单来说,就是讲x=x+1这种式子用x+=1来表达。可以让代码显得更加简练和紧凑,但实质上并无差别。

有意思的是'*=’。经过前几章的学习,我们知道序列可以通过*来制造一个重复多次的序列。例如:

因为a*2是产生一个新的列表,所以重新赋值给a会改变a的地址。但是如果a*=2的话,虽然得出来的值一样,但是是会在原对象的基础上改变,所以地址没变。

但是如果序列是immutable(不可变的),像元组,是不能在原对象的基础上进行任何改变的,所以一定会创建新的元组,因此地址会改变。

 

5.3语句块

语句块是在条件为真(条件语句)时执行和执行多次(循环语句)的一组语句,需要在在代码前放置空格(python为四个)来缩进语句。

tab和空格的区别:tab和空格键都可以缩进。以python为例,在ide中设置tab缩进为四个空格长度后,两者表现是一样的,但是在其他人的ide中,如果设置tab为其他数量(例如x)的空格,那么tab键表现出来的缩进则是x格空格,而不再是4个。所以标准推荐方法是直接用空格而不是tab,那么在任何情况下缩进都会是4个空格。

另外,python对于缩进的要求很严格。像在java和c语言中,缩进更多的是为了程序的易读性,对程序的运行并不会有任何的影响,而在python中,错误的缩进会直接导致错误的运行,甚至报错。

在python中,是用冒号(:)用来标识语句块的开始。更多的语句块的例子可以在下面的条件语句和循环语句中找到。

 

5.4条件和条件语句

5.4.1布尔变量(boolean)

布尔变量有两个标准值,“True”和“False”(真和假),True==1, False==0。。下列的式子,作为布尔表达式时,会被解释器当成假:

False, None, 0, "", (), {}

除了这几个以外,其他的都会被解释器当成真。

请注意,有些函数返回值为0并不一定代表是返回False。例如Java中的String的compareTo函数,返回值的正负值代表比较的两个变量的大小关系,只有当返回值为0是才代表两个变量相等。

 

5.4.2条件执行和if语句

如果之前有其他语言的编程基础的话就很容易理解下面的部分。if后面的括号内就是条件,如果条件结果为True,就运行下面代码块的内容。如果结果为False,则直接跳过这一部分。

a=1
b=1
if (a==b):
    print('a equals to b')

结果:

可以添加else字句。如果if后面的条件结果为False,就运行else后面的代码块:

a=1
b=2
if (a==b):
    print('a equals to b')
else:
    print('a does not equal to b')

结果为:

如果需要检查多个条件,则可以添加elif(相当于其他语言的else if)字句:

a=1
b=2
if (a>1):
    print('a is greater than 1')
elif (b>1):
    print('b is greater than 1')
elif (a<b):
    print('a is smaller than 1')
else:
    print('None of the conditions has been met')

结果为:

代码的运行顺序是从第一个condition开始检查,因为(a<1)返回False(a等于一而不是小于1),所以跳过代码块直接检查第二个条件。因为b=2,所以(b>1)返回True,运行后面的代码块。运行完之后将直接跳过if-block后面的代码。所以,虽然第三个条件(a<b)返回True,但因为第二个条件已经已经满足了,后面的代码就不会被运行了,'a is smaller than 1'就不会被打印出来。

 

5.4.3if的嵌套

if的嵌套就是在if语句里面再加上新的if语句,并不难理解。主要是注意下在新的if语句中,需要再一次的缩进。避免犯出下面的错误。

a=2
b=1
if (a>1):
    print('a is greater than 1')
    if (b==2):
        print('Both conditions are met. Position 1')
    print('Both conditions are met. Position 2')

很明显,代码的本意是满足(a>1)的条件,打印'a is greater than 1‘,两个条件都满足时,打印'both conditions are met'。最后两句输出语句的区别在于一个缩进4个空格,一个缩进8个空格。既满足a>1又满足b==2会打印Position 1(缩进8格)的语句,而不是Position 2(缩进4格)。结果是:

因为b==2返回False,不应该打印出‘Both conditions are met’。所以Position2并不在嵌套里的if里面,而是在最外层的if中。正确的代码应该是:

a=2
b=1
if (a>1):
    print('a is greater than 1')
    if (b==2):
        print('Both conditions are met.')

结果就只有:

 

5.4.4更复杂的条件

各类运算符:

 

1.比较运算符:

简单来说,就是比较x,y的大小关系。只有当x,y类型一样或者接近时,比较才有意义。比较1000和‘zyx’的大小是毫无意义的。

 

2.相等运算符(==):

比较两个变量的值是否相等。

 

3.同一性运算符(is, is not):

判断x,y是否是指向同一个物体。例如:

(对于每项比较返回的布尔值的解释可以参考上一章字典的软复制(soft copy)部分。)

 

4.成员资格运算符(in, not in):

检查元素是否存在于某个变量中。例子可以参考上一章字典的key in dict。

 

5.字符串和序列比较

像上面的例子,一般来说,字符串和序列的比较是从第一个元素开始比较,相等的话再开始比较下一个元素,一直到其中一个字符串或序列结束或者两个元素不一样。需要注意的是在字符串的比较中,要注意下大小写的问题。一般来收都是先处理成都是大写或者小写再比较。而在序列的比较中,每个位置的元素类型最好一样。比如:

 

这个序列的比较看似是没有问题的,没有报错,而且能返回一个True。但是可以看到左边的序列第二个元素是int,而右边的序列第二个元素是一个序列[1,1]。如果需要比较到第二个元素的话,就会报错。

 

6.布尔运算值(and, or, not)

not就是negate,将True变成False,False变成True。

and(和):两边值都为True时,返回True,否则返回False。

or(或):只要有一边的值为True时,返回True,否则返回False。

可以用and,or来连接多个条件。not用来修饰条件。

需要注意的是,像and,是需要两边条件都为True时,才返回True,所以当计算第一个条件为False时,并不会再计算第二个条件,而是直接返回False。类似的对于or,如果第一个条件为True,那么将直接返回True,也不会再计算第二个条件。(short-circuit logic/ lazy evaluation)因此在条件中放入一些运算时需要多斟酌一下。

从上面的例子可以看到,由于是以0为除数,所以3/0的运行是会报错的。但是在and和or中,因为第一个条件是False和True,所以会跳过第二个条件,直接返回布尔值,3/0并不会报错。(因为根本没被运行,而3/0的错误是runtime error)

 

5.4.5断言

assert对于程序的测试是很有帮助的。他的功能是当assert的条件不被满足时,直接程序报错退出。很多时候是用来写test case。可以在assert的条件后面加‘,’再加string用来说明为什么出错。下面这个例子就是在除数为0时报错并说明理由。

 

5.5循环

循环就是一直重复某段代码直到某个条件不再被满足。

 

5.5.1while循环

用法(Pseudo-code):

while condition:
    do something

while循环中的代码块就会一直运行下去,直到condition不再被满足。

 

5.5.2for循环

在其他很多语言中,for的用法是类似于下面:

for (int a=0; a<10; a++)

这样代码块会运行十次。

而在python中,for是搭配in一起用。如果是遍历序列或者字典的话,可以直接用for变量in序列/字典。

序列:

字典:

如果要像其他语言一样迭代某范围的数字,可以用内建函数range:

range函数的两个参数代表着初始(包括)和结束(不包括)的index。上面的例子相当于其他语言的:

for (int a=0; a<10; a++){
  print('Run' + a + 'Times')
}

 

5.5.3一些迭代工具

1.并行迭代(zip)

 zip的功能就是将两个序列压缩成一个列表,然后返回那个列表的迭代器(zip object,python 3)。由于返回的是迭代器,所以并不能用index来获取element。迭代器可以理解为遍历一个容器(字典,序列等)的一个接口,更多的解释和例子会在第九章中提到。

例子如下:

 

2.编号迭代(enumerate)

enumerate在迭代式会同时返回索引和数据。

 

3.翻转(reversed)和排序迭代(sorted)

功能同列表中的reverse和sort类似,但是是作用于可迭代对象上,而不是原地修改对象。

需要注意的是sorted是直接返回一个列表,但是reversed是返回一个迭代器。

 

5.5.4跳出循环

break和continue:在迭代时,有时并不一定循环到结尾。例如,检查一个数组中是否含有数字1,从第一个元素开始检查,如果检测到了1,就可以直接退出迭代,而不用继续检查其他元素。像这种情况,则需要利用break或者continue来跳出循环。

break和continue区别:break是跳出循环,而continue是跳过当前循环的剩下部分,直接开始下一循环。在其他语言中的switch-case语句中经常用到。

需要注意的时,如果在循环里面嵌套循环,如果break是在里循环中,一旦运行到break,只会会跳出里循环,而不会跳到外循环之外。

 

5.6列表推导式(list comprehension)--轻量级循环

简单来说,就是利用已有的列表创建新列表。像下面的例子,就是将range(10)这个列表的每个元素求平方,再存到另一个列表中。

可以和更多的for和if语句一起用

在上面的例子中,x和y的所有元素都会组合成一对,不满足if条件的会在结果中去除。

 

5.7pass,del和exec&eval

pass:pass就是一个什么都不运行的语句。因为在python中,空代码块是不被允许的,如果暂时不知道在if或者其他需要代码块的语句需要填什么的话,可以先填写pass。

del:我们都知道,变量实际是对对象的引用,在赋值给一个变量之后又赋其他值给同一个变量,只是让变量成为另一个对象的引用。del的功能则是完全删除变量对对象的引用,以及移除名字本身。例如del x之后,再次引用x则会显示undefined(未定义)。

exec:执行字符串中的python语句,并不返回任何对象:

eval:计算python表达式,返回结果值:

从string或者code对象中执行代码也是python作为动态语言的一个特色。可以应用在服务器的热部署方面,除非大的版本更新,可以只重新部署改动的部分,而不是所有代码。exec和eval更多的实际操作可以等到有具体需求时再去了解。exec的原理可以参考下面的文章:

http://lucumr.pocoo.org/2011/2/1/exec-in-python/

转载于:https://www.cnblogs.com/tanfengji/p/9217534.html

相关文章:

  • C++虚函数和多态性的关系【virtual】之一
  • 预编译理解
  • [拒绝毒瘤的小清新系列] give you a tree
  • 代码
  • c++ 前向引用详细解说
  • telnet不能用!!!提示:-bash: telnet: command not found
  • objective-c类别(Category)详细解说
  • 【3dsmax2016】安装图文教程、破解注册以及切换语言方法
  • 需要谈谈的 游戏测试改良流程(二)
  • python实现批量修改文件名
  • 需要谈谈 游戏测试的一些事项(四)
  • 性能测试day02_预习知识
  • selenium python 启动Firefox
  • 需要谈谈的游戏测试(五)
  • 七 Git版本控制
  • 《剑指offer》分解让复杂问题更简单
  • 【面试系列】之二:关于js原型
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • centos安装java运行环境jdk+tomcat
  • js操作时间(持续更新)
  • JS题目及答案整理
  • mysql常用命令汇总
  • PAT A1050
  • python 装饰器(一)
  • React Native移动开发实战-3-实现页面间的数据传递
  • Redis学习笔记 - pipline(流水线、管道)
  • Shadow DOM 内部构造及如何构建独立组件
  • spring cloud gateway 源码解析(4)跨域问题处理
  • storm drpc实例
  • 番外篇1:在Windows环境下安装JDK
  • 基于遗传算法的优化问题求解
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 区块链共识机制优缺点对比都是什么
  • 如何学习JavaEE,项目又该如何做?
  • 算法之不定期更新(一)(2018-04-12)
  • 我这样减少了26.5M Java内存!
  • Hibernate主键生成策略及选择
  • Spring Batch JSON 支持
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #Z2294. 打印树的直径
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)计算机毕业设计高校学生选课系统
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (十六)串口UART
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转载)深入super,看Python如何解决钻石继承难题
  • (状压dp)uva 10817 Headmaster's Headache
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET 命令行参数包含应用程序路径吗?
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。