文章目录

  • 1 前言
  • 2 什么是编程,什么是计算机语言,什么是Python
  • 3 Python程序能做什么,不能做什么
  • 4 Python编译器的安装
  • 5 第一个Python程序
  • 6 Python的基础语法
    • 6.1 书写规则——逻辑行与物理行
    • 6.2 什么是注释
    • 6.3 变量
      • 6.3.1 什么是变量
      • 6.3.2 变量的类型
      • 6.3.3 几种常用类型简介
        • 6.3.3.1 字符串型
          • 声明字符串变量
          • 转义字符
          • 用单引号与双引号的区别
          • 字符串的切片
          • 字符串的拼接
          • 获取字符串的长度
          • 查找字符串在另一个字符串中出现的位置
        • 6.3.3.2 列表型
          • 列表的声明
          • 列表的切片
          • 获取列表的长度
          • 向列表插入元素
          • 合并两个列表
          • 删除列表的元素
          • 查询元素在列表中的位置
        • 6.3.3.3 字典型
          • 字典类型的声明
          • 获取Key的Value
          • 添加新的元素
          • 合并两个字典
    • 6.4 操作
      • 6.4.1 操作符
      • 6.4.2 值传递与引用传递
      • 6.4.3 算术运算
      • 6.4.4 特殊的赋值运算
      • 6.4.4 关系运算
      • 6.4.5 位运算
      • 6.4.6 类型转换
        • 数字转字符串
        • 字符串转数字
    • 6.5 程序结构
      • 6.5.1 顺序结构
      • 6.5.2 条件结构
        • if...else结构
        • if结构
        • if...elif..else结构
        • 布尔运算
      • 6.5.3 循环结构
        • For结构
        • break和continue
        • For...else结构
        • while结构与while...else结构
    • 6.6 函数
    • 6.7 作用域
    • 6.8 类
    • 6.9 包与模块管理
    • 6.10 站在巨人的肩膀上-引用第三方库
    • 6.11 高级语法
  • 附录
    • 1 什么是保留字
    • 2 什么是二进制,十进制,十六进制
      • 如何在python中表达十进制、二进制和十六进制数
    • 3 什么是位,什么是字节
    • 4 如何表示负数,什么是补码

1 前言

工作了六七年,自己还是一个平凡的小程序员。本以为能借着互联网的风飞起来,但回头看一直在地上。家里突发的一点小变故使我开始思考能为孩子留下点什么。思来想去,还是留下一些知识吧,其他的我真的也没有。既然我是一个程序员,那就写一点关于编程的知识留给她。
早些时候,我一直认为计算机编程语言要从C语言学起,因为C语言非常基础,学会了其他语言的学习自然融汇贯通。但是现在我改变了想法,因为C语言太枯燥了,而且还得事先学一点计算机系统组成的知识才能学得顺利。这有点像本来想学煮饭的你,却发现不得不先弄明白如何种水稻,你可能很快就放弃了学煮饭这件事。而Python就好比是超市里的大米,买回来,洗一洗直接用就好。
所以,我决定写一个Python教程留给她。教程不会只有Python语法一类的东西,同时也会插入一些计算机组成、数据结构等方面的知识。希望她会喜欢。

2 什么是编程,什么是计算机语言,什么是Python

编程指的是编写计算机程序。这就引出一个问题,“计算机程序”又是什么呢?“

计算机程序”的理论定义挺复杂的,但可以简单理解为:指挥计算机工作的命令合集。比如:

请计算3+5的结果
将计算结果显示在屏幕上

上面的两句话就可以理解为一个简单的程序,但它还不是计算机程。这简单的两句话之所以是程序,是因为它表达清楚了两件事:1要做什么事情;2按照什么顺序做。

但是它还不是一个计算机程序,因为计算机是看不懂汉语的。只有用计算机能看懂的方式表达的程序,才可以叫做计算机程序。而计算机能看懂的是“二进制数据流”,如果把上面的程序用”二进制数据流“表达,可能是下面的样子:

00101010010101001010
11111111000000000100
00101001000100101000
01000000010010010000

这是一个很简单的程序,用“二进制数据流”表达就如此的不可理解。如果开发一个像微信那么复杂的程序,必须用“二进制数据流”去编写的话,估计没人能做的到。为了解决这个问题,人们想创造一个翻译。这个翻译应该即明白汉语,也明白“二进制数据流”。这样人们就可以用自己好理解的汉语写出程序,然后让翻译把汉语程序翻译为“二进制数据流”,就得到了计算机程序。在计算机领域,人们称呼这个翻译为“编译器”。编译器本质上也是一个计算机程序。

前面说了,人们想创造一个即明白汉语也明白“二进制数据流”的翻译,但实践发现这太困难了。难点就在于汉语或者说所有人类日常交流的语言都有一个问题,就是语言歧义。比如东北话里那就经典的“你愁啥?”,有些情况就是在问你看见了什么,但有些情况绝对不是在询问你看见了什么。

这种歧义问题在人类的自然语言当中大量存在,给创造翻译或者说创造编译器带来了巨大的难度。所以,为了降低难度,计算机领域的科学家们不得不发明一种语言,这种语言应该是对人类来说好理解,同时又是没有歧义的。这种语言被称为计算机语言。

Python就是众多计算机语言中的一种,其他的还有C语言、Java语言等等几十种。而负责翻译Python语言的翻译,就叫做Python编译器。用Python语言编写的程序就可以称为Python程序。

PS:其实人们一直没有放弃创造一个能够理解汉语(或其他人类语言)的翻译,搜索技术和人工智能技术对此都有巨大的贡献,但直到今天也没有一个技术能够完全准确的理解人类的语言。

3 Python程序能做什么,不能做什么

Python是一种计算机语言,而计算机语言的作用前文已经说过,就是用来编写计算机程序,指挥计算工作的。所以,理论上讲只要是计算机能做到的,都可以通过编写一个Python程序来完成。

但实际上Python程序还是受到两面的限制:

  1. 操作系统限制。新买的计算机都需要安装一个windows,这个windows就是操作系统。其实手机也是一种计算机,android和ios也是操作系统。操作系统就像是一个计算机的大管家,Python程序想做的事情必须在这个管家的监督下做,如果管家不让你做,你就做不了。有些事情甚至不能直接去做,必须拜托给管家,让管家帮你去做。所以,Python程序的能力受到操作系统这个管家的限制。
  2. Python编译器的翻译速度。前文已经说过,Python编写的程序,需要编译器帮忙翻译,才能让计算机明白你的指令,但翻译是需要时间的。如果你的程序对执行时间非常敏感,需要执行的非常快,则由于翻译时间的问题,Python可能做不到那么快。对于这个“快”也要有一个正确的认识,对于新手能写出的程序来说,我认为Python编译器已经翻译的足够快了。而对于真的需要非常快的程序,Python也有弯道超车的办法,但需要累积一些知识后,才能明白怎么做以及为什么这么做。

读到这比较细心的人对于翻译速度的问题可能会有一个疑问。既然翻译影响速度,可以一次翻译完,再执行,这样不就快了吗?其实“翻译”只是我为了说明问题给出的一个形象比喻,Python程序真实的执行过程是挺复杂的,要讲明白还需要引入jit技术等等概念,所以在此问题上不要纠结,有这么个印象就好。

4 Python编译器的安装

因为windows的用户最多,所以以下涉及具体操作的部分都在window10环境下进行展示。如果你是linux用户,可能有一些不同,但既然能会用linux系统,我相信这点不同还是有能力处理的。
Python的编译器可以在Python的官网下载:Python官网
网站是英文的,找到download板块就可以下载到最新的Python编译器。
然后就想安装普通程序一样,将Python编译器安装在电脑上即可。中间的一些选项除了安装在位置选择一下,其他的默认就好。
然后在开始菜单中找到Python编译环境的入口,如图:

启动后会打开一个叫做PythonShelll的界面,如图所示。它的一个重要作用就是展示命令的执行结果。

然后点击PythonShell菜单栏的File->NewFile,则会进一步打开Python语言编辑器。它类似一个txt编辑器,是用来编辑Python语言的。
这里要说明的是,PythonShell和Python语言编辑器都不属于Python的编译器一部分。他们仅仅是安装编译器时,默认提供的一些编程小工具而已。当你走过入门阶段以后,你一定会使用一些第三方的工具来代替他们。

5 第一个Python程序

讲到这里还没有讲有关Python语言细节的任何东西,所以也写不了任何Python程序。但我还是想展示一个非常简单的程序,一方面增加感性认识,一方面为下面的讲解做铺垫。

ans = 2+3  #将2+3的结果保存在ans中
print(ans) #将ans在屏幕(准确的说是PythonShell)中显示

上面就是用Python语言编写的一个程序,程序的意思很好理解,就是我们前面举得例子。将这段程序粘贴到Python编辑器中,然后点击执行(如图所示)。就可以在PythonShell中看到执行结果了。


在左侧的PythonShell中可以看到,2+3的结果是5。这当然是一个非常幼稚的程序,但它也是一个好的开端,使得我们对Python程序有了一个具象的认知。
另外,我们可以看到在Python编辑器中不同的语句被标记为不同的颜色,这个功能叫做“语法高亮”,他可以帮助我们更方便的阅读程序。

这里再说一下程序中的最后一句:

print(ans) #将ans在屏幕(准确的说是PythonShell)中显示

这个print叫做内置函数,作用就是将计算的结果显示在PythonShell里,现在不必深究,用法可以照猫画虎,后文中我们会经常用到。

最后,如果你能举一反三,你就会发现你已经拥有了一个Python计算器,只需要把“2+3”换成其他的运算表达是即可。

6 Python的基础语法

从这一章开始,我们将从上面的小例子开始,正式进入Python语言细节的说明。
我个人觉得初学之时,具象要比抽象更好,所以每讲一处,我都会展示一些例子加以说明。但这样也有不好的地方,就是很难形成体系,影响以后的高级进阶。鱼和熊掌不可兼得呀。
任何一种语言都由四方面组成:词汇、语法、书写格式及发音。计算机语言自然也是如此,不过计算机语言是写个计算机“看的”,所以没有发音的设计。我将从语法的角度入手,在介绍语法的过程中逐步带入其他的概念来讲解Python语言的细节。

6.1 书写规则——逻辑行与物理行

通过第五章的例子我们可以看到,Python程序是一行一行写出来的,每一行就代表一个需要计算机执行的命令。在以后学习了更多的语法规则之后,我们会发现有时一个命令需要多行才能书写完成。
需要注意的是,这里的行指的是逻辑行。在Python语言中关于程序的行,有逻辑行物理行的概念。下面就通过一个例子说明一下。

ans = 2 \+3  #将2+3的结果保存在ans中
print(ans) #将ans在屏幕(准确的说是PythonShell)中显示

上面的程序如果从行号来看有三行,这个三行说的就是物理行。物理行指书写时实际的行数。但如果从逻辑行的角度来说,这个程序只有两行。因为物理行的第1、2行通过一个连接符"\"连接在了一起。
这种连接物理行的做法,目的是为了使程序更容易阅读。假设要计算200个数相加,如果都写在一行,将会非常不好理解。但有了逻辑行的方法,我们可以将200个数写在10个物理行上,并用连接符拼接为一个逻辑行,这会非常好阅读。下面可以看一下效果:

ans =  2 +2  +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2\+2 +2  +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2\+2 +2  +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2\+2 +2  +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2\+3
print(ans) #将ans在屏幕(准确的说是PythonShell)中显示

可以想象如果都写在一行,将会多么难以阅读。

6.2 什么是注释

“注释”顾名思义,就是标注与解释。程序是写给计算机“看”的,同时也是给人看的。比如:

print(ans) #将ans在屏幕(准确的说是PythonShell)中显示

“#” 前面的print(ans)就是给计算机看的,而后面的话自然是给人看的。所以,不难发现注释的作用就是让写程序或者阅读程序的人,能够更加快速的明白这段程序是什么意思。有时,注释也用来给阅读程序的人一些提醒,比如:

#FIXME:下面的函数仅保留接口定义,功能待完善
#作者:jh
def GetLen():return 1

通过这两个例子,我们可以看到Python语言中将"#"后面的认为是注释。注释既可以写在代码的同一行,也可以不同行。注释的具体内容能说明白问题就好,没有什么规定。

良好的注释是一个程序员素质的体现,有很多建议帮助程序员写出好的注释。还有一些注释有特定的格式,这种规定是一种行业的“潜规则”,并不是Python语言的规定。比如我前面例子中用到的“FIXME”。不过再还没有踏入程序员这个行业之前,真没有必要关注这些注释写法的“潜规则”,能说明白就好,不必在意格式。以后,如果真的成为一名程序员,阅读的程序代码多了,自然也就知道如何写了。

最后,还用一种特殊的注释方式,这是在Python程序中特有的一种方式:用长字符串代替注释。比如:

'''
FIXME:下面的函数仅保留接口定义,功能待完善
作者:jh
'''
def GetLen():return 1

在书写多行注释的时候,我们不得不在每一行的前面都加上"#",这是Python语言语法规则决定的。但如果写一个几十行的注释,这样就很麻烦。为此,很多Python程序员采用了取巧的做法——声明一个长字符串。

python语言规定,在''' '''之间的部分是字符串变量,可以换行。上面的例子就利用了这一点,那两行看起来像注释的东西,其实是声明了一个长字符串,人能看懂,计算机也能“看”懂。这种取巧做法的详细原理会在后文介绍,这里知道这个形式就好。

6.3 变量

6.3.1 什么是变量

所谓变量就是一个临时存放计算结果的地方,还以下面的程序为例,ans就是一个变量。它的作用就是临时存储“2+3”这个计算的结果。

ans = 2+3  #将2+3的结果保存在ans中
print(ans) #将ans在屏幕(准确的说是PythonShell)中显示

其实更准确的说,ans是变量名,变量名就是变量的一个标签。我们将计算结果放在一个变量里,并贴上一个叫ans的标签。当我们以后需要读取这个变量时,就可以通过ans这个标签得到。
在实际的编程过程中,我们从来不这么细的区分变量和变量名的概念。统统直接说ans就是变量。
Python对变量名的选择是有一定限制的,具体如下:

  1. 不能以数字开头
  2. 不能有空格
  3. 不能是保留字(有些书叫做关键字,具体的含义请参考附录中的内容)
  4. 在有些操作系统中,变量名的长度也有限制

这些限制并不苛刻,但变量名也最好不要随便起的。可读性高的变量名是一个程序员能力的体现,为了起一个好的变量名,我们可以遵循以下的建议:

  1. 除非程序很简单,不要用a1,a2这种毫无意义的名字,最好是animal、car等有意义的名字
  2. 变量名不宜太长,可以用缩写
  3. 有特殊用途的变量名应该以“_”开头,如“_ignoreValue”;
  4. 不要用“__”,即双下划线开头给变量取名字。

6.3.2 变量的类型

前文说过,变量就是一个仓库用来存储计算的结果。但是,不同计算结果需要不同大小的仓库来存储(也就是需要的字节数不同,关于什么是字节可以参见附录中的说明)。如果我们都用最大的仓库,就会很浪费存储空间。一个计算机中的“仓库”数量是有限的,为了高效利用有限的存储空间,计算机语言的设计者将这些仓库分为了不同的类型,每种类型的大小是不一样的。

不过,Python的设计者却刻意的隐瞒了这些细节。这是因为过去计算机资源十分珍贵,程序员在设计程序时需要非常谨慎的选择变量类型,以便节约资源。但 在Python诞生的时候,计算机的存储空间已经大的惊人,所以Python的设计者希望降低程序员对这种底层问题关注度,将精力更多放在程序逻辑的设计与实现上。

说的直白点,空间不够了就加一块内存呗,又没有几个钱。不过,这也是为什么,今天的硬件能力已经比十年前翻了几千倍,而我们依然觉得不够用的原因之一。

作为一个Python程序员,你关心变量类型的目的不应该是空间使用的问题,而可能是:

  • 此类型默认提供的便利的方法。比如字符串类型默认提供了分割、拼接、查找等方法,如果你需要直接用就可以;
  • 此类型能更好的解决逻辑问题。比如如果你需要做一个类似数据库的东西,显然用字典类型存储数据更为合适;

Python中变量的常见类型有以下几种(这个划分我觉得不是特别专业,而且不全,但比较实用)

类型名称 英文简称 说明
整数 int 如1,2,3,4,5,6
浮点数(小数) float 如1.1,3.2
字符串 str 如 ‘我是超人’ ,下文会有单独的章节细讲
布尔值 bool 只有True和False两种值,表示真和假
列表 list 下文会有单独的章节细讲
字典 dict 下文会有单独的章节细讲
元组 set 下文会有单独的章节细讲
class 这里指自定义类型,下文会有单独的章节细讲
空值 None 空值在Python中是一种类型,这里要强调的是它并不是0
函数(方法) function(method) 下文会有单独的章节细讲

如果你看一些专业性很强的书籍,可能不是这么讲的,因为本质上Python中的变量类型只有一个class。但我觉得以上的划分便于你与其他程序员进行交流,非常精准的学术说法反而会把大家弄晕。

我们可以使用Python提供的type方法查询变量类型,举例如下:

ans = 2+3 #将2+3的结果保存在ans中
print(type(ans)) #将ans在屏幕(准确的说是PythonShell)中显示

运行结果如下:

我们可看到变量ans的类型是int

大家可以试试修改ans的计算公式,比如:

ans = 2+3.0 #将2+3.0的结果保存在ans中
print(type(ans)) #将ans在屏幕(准确的说是PythonShell)中显示

你会发现类型是float

6.3.3 几种常用类型简介

为了以后讲解的需要,下面会针对几个常用的变量类型的特点和使用方法进行简介。简介当然不会很全面,原则就是后文会用到什么,这里就介绍什么。

在这个小章节,许多解释说明的东西我就直接写在注释中了,请多注意看注释。

6.3.3.1 字符串型

声明字符串变量

所谓声明字符串变量,就是将字符串赋值给一个变量的过程。

#用双引号声明字符串,只能是一行
ans1 = "I am ans1"#用单引号声明字符串,只能是一行
ans2 = 'I am ans2'#用''' ''' 声明长字符串,可以是多行,但看不见的空格和换行符等也都会被
#认为是字符串的有效部分,参考运行结果
ans3 = '''I am a long stringI am ans3'''print(ans1) #将ans1在屏幕(准确的说是PythonShell)中显示
print(ans2) #将ans2在屏幕(准确的说是PythonShell)中显示
print(ans3) #将ans3在屏幕(准确的说是PythonShell)中显示

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
I am ans1
I am ans2I am a long stringI am ans3>>>
转义字符

首先看一个例子:

#在这个字符串的声明中,有一个字符是\n
ans1 = "I am Line1\nI am Line2"print(ans1) #将ans1在屏幕(准确的说是PythonShell)中显示

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
I am Line1
I am Line2
>>>

本来是写在一行的字符串,运行结果却是两行。这个换行的行为就是“\n”这个字符完成的,“\n”也因此被称为换行符。

这种字符的特点是;它们对字符串的显示有影响,但英文中并没有一个可见的字符代表它们。所以,在计算机中采取了**“\+可见字符”的方式来表达这些特殊的字符。这些字符也被称为转义字符**。其他的转义字符还有:

字符 含义
\r 回车符,将光标位置移到本行开头。
\t 水平制表符,也即 Tab 键,一般相当于四个空格。
\a 蜂鸣器响铃。注意不是喇叭发声,现在的计算机很多都不带蜂鸣器了,所以响铃不一定有效。

Python语言中的转义字符还有很多,这里只是抛砖引玉的给大家看一下。但我负责任的说,除了"\n"等少数几个,其他的很少用。

转义字符是**“\+可见字符”**形式定义的,这就带来一个问题:"\"字符,即反斜线符怎么办。例如,我就是需要显示如下的一句话:

I am Line1\nI am Line2

前面的例子已经可以看到,如果在字符串声明中直接使用"\n"是会被换行的,不会显示“\n”。在Python语言中解决这个问题有两种方式:

#第一种,使用"\\",它是反斜线的转义字符。因为单反斜线被用来指明其他转义字符了
#所以,反斜线本身就使用双反斜线来代替
ans1 = "I am Line1\\nI am Line2"#第二种,在字符串前面加r。这种方式会认为字符串中没有转义字符,所有字符都是其自身
#这种方式不限于用双引号,单引号也可以
ans2 = r"I am Line1\nI am Line2"print(ans1) #将ans1在屏幕(准确的说是PythonShell)中显示
print(ans2) #将ans2在屏幕(准确的说是PythonShell)中显示
用单引号与双引号的区别

Python语言中字符串可以有单引号声明和双引号声明两种方式,本质上也是了解决转义的问题。比如下面的程序:

#如果要显示的字符串本身就有双引号,则用双引号声明这个字符串就会有问题。
#Python的编译器不明白那个双引号是声明字符串的,那个是字符串的内容
ans1 = "I say: "Lucy" "print(ans1) #将ans1在屏幕(准确的说是PythonShell)中显示

解决这个问题有两种方法:

#1. 将使用双引号的转义符\"
ans1 = "I say: \"Lucy\" "#2. 使用单引号声明字符串
ans2 = 'I say: "Lucy"'print(ans1) #将ans1在屏幕(准确的说是PythonShell)中显示
print(ans2) #将ans2在屏幕(准确的说是PythonShell)中显示

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
I say: "Lucy"
I say: "Lucy"
>>>

同理,对于单引号也有类似的问题和解决方法。这里不再赘述。

字符串的切片

所谓切片,就是获取字符串的一部分。比如:

#原始字符串
ans1 = "我是一个字符串"#获取由第一个字符和第二个字符组成的子字符串
#
#这里有两点要说明:
#1. 计算机程序中是从0开始数数的,这是一种继承下来习惯。
#   所以第0个才是我们生活中常说的第一个,这一点要格外注意。
#   以后凡是涉及到第0个的说法,请不要奇怪。
#
#2. 可以看出[0:2]就是切片操作,紧跟在ans1这个变量的后面,意思就是
#   获取从第0个开始,到第2个之前的部分。注意是第2个之前,不包括第2个。
ans2 = ans1[0:2]#获取第3个字符
#ps:如果你理解了什么是第0个,不妨先猜测一下ans3的值是什么
ans3 = ans1[3]#获取倒数第一个字符
#既然第0个是最开头的字符,那么最后一个字符自然是第-1个
ans4 = ans1[-1]#获取第0个开始,到倒数第2个之前的所有字符
ans5 = ans1[0:-2]print(ans1) #将ans1在屏幕(准确的说是PythonShell)中显示
print(ans2) #将ans2在屏幕(准确的说是PythonShell)中显示
print(ans3) #将ans3在屏幕(准确的说是PythonShell)中显示
print(ans4) #将ans4在屏幕(准确的说是PythonShell)中显示
print(ans5) #将ans5在屏幕(准确的说是PythonShell)中显示

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
我是一个字符串
我是
个
串
我是一个字
>>>

对照一下,看看运行结果和你想象中的有什么不一样。重点是理解什么是第0个。

字符串的拼接

字符串既然可以切片,自然也可以拼接。所谓拼接就是将两个以上的字符串连接在一起。

#第一个字符串
ans1 = "我是一个"#第二个字符串
ans2 = "程序员"#使用“+”好拼接两个字符串。
#这里需要强调的是“+”只能用来拼接两个字符串类型的变量。
#如果有一个变量不是字符串类型,需要先进行类型转换,才可以拼接。
ans3 = ans1 + ans2print(ans3) #将ans3在屏幕(准确的说是PythonShell)中显示

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
我是一个程序员
>>>
获取字符串的长度

所谓字符串长度是指一个字符串包含多少个字符。

Python语言提供了len()内置函数实现获取字符串长度的功能。

#第一个字符串
ans1 = "我是一个"#利用len()函数,获取字符串长度。
ans1_len = len(ans1)print(ans1_len) #将ans1变的长度在屏幕(准确的说是PythonShell)中显示

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
4
>>>
查找字符串在另一个字符串中出现的位置
#声明第1个字符串
str1 = '我是一个好人,真的是好人'#声明第2个字符串
str2 = '好人'#查找第二个字符串在第一个字符串中出现的位置
#可以使用字符串变量提供的index方法
#但此方法仅能找到第一次出现的位置
ans_index = str1.index(str2)print(ans_index)

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
4
>>>

这里对“位置”的含义再进一步说明一下。准确的说,index方法找到的是str2的第一个字符在str1中首次出现的位置。所以结果是4。

6.3.3.2 列表型

我们可以将列表理解为一种容器,它把整数、浮点数、字符、字符串等等类型的变量组合在一起形成一个整体。

这里介绍的仅仅是列表类型的一些基本操作,列表类型还有一些高级操作在后面介绍。

列表的声明
#声明一个空列表,这个列表中不包含任何元素
List1 = []#另一种形式声明一个空列表,但不常用
List2 = list()#声明一个包含整数的列表
List3 = [1,2,3]#声明一个包含混合类型元素的列表
List4 = [1,"我是字符串",False]#列表中元素也可以是列表类型
List5 = [1,2,[10,20]]print(List1) #显示List1
print(List2) #显示List2
print(List3) #显示List3
print(List4) #显示List4
print(List5) #显示List5

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[]
[]
[1, 2, 3]
[1, '我是字符串', False]
[1, 2, [10, 20]]
>>>
列表的切片

与字符串一样,列表类型也有切片操作。

#声明一个列表
List1 = [1,2,3,4,5]#获取列表中第0个和第1个元素,组成新列表
List2 = List1[0:2]#获取列表中第3个元素。
#这里需要注意,如果获取的是一个元素,则结果就不再是列表类型
#而是元素本身的类型
Item1 = List1[3]#获取第0个开始到倒数第2个之前的列表
List3 = List1[0:-2]print(List1) #显示List1
print(List2) #显示List2
print(Item1) #显示Item1
print(List3) #显示List3

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[1, 2, 3, 4, 5]
[1, 2]
4
[1, 2, 3]
>>>
获取列表的长度

获取列表的长度与字符串相同,也使用len()函数。

#声明一个列表
List1 = [1,2,3,4,5]#获取列表的长度,及包含元素的个数
List1_len = len(List1)print(List1_len) #显示List1_len

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
5
>>>
向列表插入元素
#声明3个列表
List1 = [1,2,3,4,5]
List2 = [1,2,3,4,5]
List3 = [1,2,3,4,5]#在List1的最后插入一个元素,使用append方法
List1.append(6)#在List2的第3个元素位置插入一个新元素
#运行后,你会看到List2变为[1, 2, 3, 'x', 4, 5]
#在此解释一下插入的原理:
#本来List2的第3个元素位置被整数4占据,现在你要求在此位置插入
#字符串'x',因此列表首先将整数4以及其后面的元素整体向后移动
#把第3个元素的位置空出来,然后在这个位置放入'x'
List2.insert(3,'x')#在List3的第5个元素位置插入
#因为List3只有五个元素,所以最后一个元素是第4个(别忘了从0算起的约定)
#所以,如果插入的位置比最后一个元素的位置还要大,就相当于append
#在此也可以看出append方法的好处是不需要你关心当前列表的长度,它总是插入到最后
List3.insert(5,'y')print(List1) #显示List1
print(List2) #显示List2
print(List3) #显示List3

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 'x', 4, 5]
[1, 2, 3, 4, 5, 'y']
>>>
合并两个列表

初学Python的人在列表合并的操作上,常常犯如下的错误

#声明2个列表
List1 = [1,2,3]
List2 = [4,5,6]
#将List2合并到Lis1中
#一个错误的例子
List1.append(List2)print(List1) #显示List1

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[1, 2, 3, [4, 5, 6]]
>>>

以上这个错误例子要牢记,尤其是程序写的比较复杂的时候会经常犯错。append方法的作用是插入,由于列表类型中的元素可以是混合的,所以上面的程序是将List2插入的到List1的最后,List1的长度由3变为了4。

正确的做法是使用extend方法。

#声明2个列表
List1 = [1,2,3]
List2 = [4,5,6]#正确的例子
List1.extend(List2)print(List1) #显示List1

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[1, 2, 3, 4, 5, 6]
>>>

使用extend方法,List2中的元素被合并到了List1中,List1的长度也由3变为了6。

删除列表的元素

下面介绍两种删除列表元素的方法。

#声明2个列表
List1 = [1,2,3,4,5]
List2 = [1,2,3,4,5]#第一种,使用del关键字#删除List1的第2个元素
#可以理解为:取出第2个元素,然后删除
del List1[2]#删除List2的第1个到第3个元素
#可以理解为:取出第1个到第3个元素,然后删除
del List2[1:4]print(List1) #显示List1
print(List2) #显示List2

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[1, 2, 4, 5]
[1, 5]
>>>

使用del关键字的方法有一个限制,就是你必须知道元素在列表中的位置。但有些时候,我们需要删除列表中特定值的元素,比如“删除等于5的元素”。这时可以使用列表的remove方法。

#声明1个列表
List1 = [1,2,3,4,5,5,5,5]#第二种,使用remove方法#删除List1中等于5的元素
List1.remove(5)print(List1) #显示List1

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[1, 2, 3, 4, 5, 5, 5]
>>>

这里要强调的是remove只能删除列表中遇到的第一个相等的元素,这一点也可以从运行结果看出来。如何删除所有的呢?这可能需要学习完循环结构和条件结构才能讲清楚,也算是列表高级一点点的用法。

查询元素在列表中的位置
#声明1个列表
List1 = [1,2,3,4,5,5,5,5]#可以使用index方法,查询元素在列表中的位置
#不会此方法只能找到第一个相等的元素在列表中的位置
#再次强调一下从0开始的问题#查询整数5在列表中的位置
ans_index1 = List1.index(5)print(ans_index1) #显示ans_index1

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
4
>>>

6.3.3.3 字典型

字典类型中保存的都是"Key-Value"结构的元素。所谓Key-Value结构就是在构建数据时,每一个Value都被赋予了一个Key作为标签,并且只能通过这个Key标签来获取Value。

对比来说,获取列表类型中的元素必须知道元素在列表中的位置,而字典类型则需要知道Key。

字典类型的声明
#声明第1个空字典
Dict1 = dict()#声明一个不空的字典
Dict2 = {1:"value1","2":"value2"}#由于Key是Value的索引,所以Key不许是不可改变的类型,比如数字,字符串等
#但对于Value没有什么要求print(Dict1)
print(Dict2)

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
{}
{1: 'value1', '2': 'value2'}
>>>
获取Key的Value
#声明一个不空的字典
Dict1 = {1:"value1","Key1":"value2"}print(Dict1["Key1"])

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
value2
>>>
添加新的元素
#声明一个不空的字典
Dict1 = {1:"value1","Key1":"value2"}#添加一个新的Key-Value,可以用如下方式
Dict1["Key2"] = "value3"print(Dict1)

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
{1: 'value1', 'Key1': 'value2', 'Key2': 'value3'}
>>>
合并两个字典
#声明一个不空的字典
Dict1 = {1:"value1","Key1":"value2"}#声明第二个字符串
Dict2 = {"Key3":"value3","Key4":"value4"}#将Dict2合并到Dict1中,使用update方法
Dict1.update(Dict2)print(Dict1)

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
{1: 'value1', 'Key1': 'value2', 'Key3': 'value3', 'Key4': 'value4'}
>>>

6.4 操作

6.4.1 操作符

首先介绍一下什么是操作符。

ans = 2+3 #将2+3的结果保存在ans中

这么一行简单的代码中就包含两个操作符,分别是“=”和“+”,称为赋值操作符和加法操作符。举一反三,自然还有减法操作符、乘法操作符等等。

赋值操作符的作用是:命令计算机将“=”右边的计算结果保存到左边。

加法操作符的作用是:命令计算机将“+”两边的数相加。

其实操作符有很多,比如:

+ - * / // '' % ** [] ()& << >> |

以上这些其实都是操作符,都用各自的特殊用途,我会在后文中结合用例逐一介绍。

可以看出操作符对于计算机来说就是某种命令。至于操作符的精准定义我就不提了,没什么学习的必要,除非你想自己发明一种新的计算机语言。大家只要熟悉“操作符”这个名词指的什么东西就好,免得与别人交流时不明白对方说什么。

6.4.2 值传递与引用传递

上面提到赋值操作符是命令计算机将右边的计算结果保存到左边。但在Python中大部分情况可能保存的不是真实的结果,而是结果的引用。

什么是引用,我们通过一个夸张的例子来说明一下。

假如你有一栋大别墅,你有一个非常好的朋友想借用一下开一个party。你有两种方式把房子给他:

  1. 给你朋友盖一个新的,并且大小和装修一模一样的别墅,然后借给他;
  2. 直接把现在这栋别墅的钥匙给你朋友。

第一种方式就是值传递,而第二种方式就是引用传递。

所谓值传递,就是创造一个与原始变量一模一样的新变量,然后将新变量传递出去。

所谓引用传递,就是将现有变量的一个引用传递出去,使用者可以通过这个引用找到变量,从而进行读取或修改。

这两种方式各有优势。如果你的朋友party开的比较疯狂,很可能损坏你别墅的装修,如果你采用值传递,则损坏的是新别墅,自己的老房子没影响,但这样做开销也大。如果你的朋友是一个非常有涵养的人,懂得珍惜,则采取引用传递就更为合适,开销要小的多。

Python在大部分情况下采取了引用传递,比如:

List1 = [1,2]
List2 = List1  #将列表List1赋值给List2,此时就是引用传递
List2[1] = 4  #将列表List2的第1个值改为4
print(List1) #将List1在屏幕(准确的说是PythonShell)中显示
print(List2) #将List2在屏幕(准确的说是PythonShell)中显示

运行结果:

=============== RESTART: D:/project/project_python_learn/t1.py ===============
[1, 4]
[1, 4]
>>>

通过上面的例子就可看出,列表类型就采取了引用传递。List2仅仅是List1的一个引用,当你修改List2时,其实就是修改了List1。

6.4.3 算术运算

简单的算术运算就是加减乘除,但python提供了更多的算术运算符。

运算符 功能
+ 加法
- 减法
* 乘法
/ 除法
% 取余数,如4.4%2=0.4 5%2=1
// 向下取数,如4.4//2=2 7//2=3
** 平方,如3**2=9
() 计算优先级

这里要强调的是计算的优先级问题。我们都知道先算乘除,在算加减,但取余数和乘除放在一起先算那一个个呢?比如:
5∗2%35*2\%3 5∗2%3
这种情况不如写成:
(5∗2)%3(5*2)\%3 (5∗2)%3
一目了然,不会犯错。这只是一个比较简单的例子,有时一个公式可能有10几行那么长,括号的使用十分必要。

6.4.4 特殊的赋值运算

前文已经提到过赋值运算符,就是"="。等号是最简单的赋值运算,结合算术运算符,python还提供了几个较为复杂的赋值运算符。这些特殊的赋值运算符在循环结构中较为常用,后文我们会有所涉及。

运算符 描述 实例
= 简单的赋值运算符 c = a + b 将 a + b 的运算结果赋值为 c
+= 加法赋值运算符 c += a 等效于 c = c + a
-= 减法赋值运算符 c -= a 等效于 c = c - a
*= 乘法赋值运算符 c *= a 等效于 c = c * a
/= 除法赋值运算符 c /= a 等效于 c = c / a
%= 取模赋值运算符 c %= a 等效于 c = c % a
**= 幂赋值运算符 c **= a 等效于 c = c ** a
//= 取整除赋值运算符 c //= a 等效于 c = c // a

6.4.4 关系运算

所谓关系运算就是比较大小,有时也被称为逻辑运算。

运算符 描述
== 等于 - 比较对象是否相等
!= 不等于 - 比较两个对象是否不相等
> x>y 大于 - 返回x是否大于y
< x<y 小于 - 返回x是否小于y。
>= x >=y 大于等于 - 返回x是否大于等于y。
<= x<= y 小于等于 - 返回x是否小于等于y。

这里要强调的是======和!=!=!=这两符号。有时他们比较的并不是值,而是地址,所以运行的结果可能和你想象的不同。不过,现在还没有办法举例子,这需要掌握“类”这种数据类型才行。

6.4.5 位运算

位运算是关于二进制数的运算。什么是二进制数以及如何在python中表达二进制数,请参考附录。

位运算包含以下6种。

运算符 描述
& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
^ 按位异或运算符:当两对应的二进位相异时,结果为1
~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。
<< 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。
>> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数

下面举例说明一下:

a = 10 #二进制表示为1010
b = 6  #二进制表示为0110print(a&b)   #结果为2, 二进制表示为0010
print(a|b)   #结果为14,二进制表示为1110
print(a^b)   #结果为12,二进制表示为1100print(a<<1)  #结果为20,二进制表示为10100
print(a>>1)  #结果为5, 二进制表示为0101

这里要特殊强调的是取反操作,可能和你想象的不一样。比如:

a = 10 #二进制表示为1010print(~a) #结果为-11

从取反操作的定义看,101010101010按照每一位取反应该是010101010101,这个结果应该是5才对,为什么是−11-11−11呢?

这是因为我们忽略了数字在计算机中使用补码表示的这一问题。关于补码的概念,请参考附录。

下面我们来分析一下这个问题。

  1. a的完整二进制表示应该是 0000 1010 而不是1010,因为数据至少要占用一个字节,即8位。
  2. 所以a取反的结果是1111 0101,首位为1,证明这是一个负数的补码。
  3. 依据补码的计算规则,将负数的补码按位取反再加一,可以得到对应的正数,则 1111 0101 取反为 0000 1010,再加一为0000 1011,十进制表示是11。
  4. 所以1111 0101 是十进制-11的补码。
  5. 所以 ~a = -11

以上的分析烦请多看几遍,否则可能被绕晕,其实有一个更为简便的公式:~a = -a-1

最后强调两点:

  • 在编程中如无必要,尽量少用取反运算,甚至少用位运算。因为补码的问题很容易出错。
  • 如果必须使用位运算,也尽量用于正整数。

以上两点是经验之谈,并没有什么特别科学的依据。

6.4.6 类型转换

这里仅仅简单介绍一下数字和字符串间的相互转换,因为这个最常用。其他以后用到再讲。

数字转字符串

将数字转为字符串,最常用的是str()函数,比如:

a = 10
b = 0xA
c = 0b1010print("当前变量a="+str(a)) #此时a用十进制表达
print("当前变量b="+str(b)) #此时b用十六进制表达
print("当前变量c="+str(c)) #此时c用二进制表达

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
当前变量a=10
当前变量b=10
当前变量c=10
>>>

通过运行结果可以看出,对于str()函数来说,无论数字使用什么进制表达的,他都将其转换为十进制形式的字符串。

如果希望得到不同进制形式的字符串,可以采用如下方法:

print("以二进制表达:"+bin(10))
print("以二进制表达:"+bin(0xA))   print("以十六进制表达:"+hex(10))
print("以十六进制表达:"+hex(0b1010))

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
以二进制表达:0b1010
以二进制表达:0b1010
以十六进制表达:0xa
以十六进制表达:0xa
>>>

另外,因为“+”号只能用于连接两个字符串型的变量,所以必须使用str()函数(或者bin,hex等函数)将数字a转换为字符串。如果不转换,你将看到一个类型不匹配的错误,比如:

a = 10print("当前变量a="+a) #注意没有使用str

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
Traceback (most recent call last):File "D:\project\project_python_learn\t1.py", line 3, in <module>print("当前变量a="+a) #注意没有使用str
TypeError: must be str, not int
>>>
字符串转数字

如下是字符串转为数字的例子:

a = '10'  #一个以十进制表示数字的字符串
b = '0xA' #一个以十六进制表示数字的字符串
c = '0b1010' #一个以二进制表示数字的字符串a_num = int(a)    #转换为数字
b_num = int(b,16) #转换为数字
c_num = int(c,2)  #转换为数字print('a的类型:'+str(type(a))+' a_num类型:'+str(type(a_num))+' a_num值:'+str(a_num))
print('b的类型:'+str(type(b))+' b_num类型:'+str(type(b_num))+' b_num值:'+str(b_num))
print('c的类型:'+str(type(c))+' c_num类型:'+str(type(c_num))+' c_num值:'+str(c_num))

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
a的类型:<class 'str'> a_num类型:<class 'int'> a_num值:10
b的类型:<class 'str'> b_num类型:<class 'int'> b_num值:10
c的类型:<class 'str'> c_num类型:<class 'int'> c_num值:10
>>>

通过这个例子还可以看出,str函数不仅能转换数字为字符串,也能转换其他类型的数据为字符串。其实,如果有转换为字符串的需要,无论数据是什么类型的,都可以使用str函数先尝试一下是不是想要的效果。

6.5 程序结构

6.5.1 顺序结构

前面所举得所用例子其实用的都是顺序结构,所谓顺序结构就是程序语句按照从上到下的顺序依次执行,这里就不再赘述了,以后我们将了解其他结构。这些结构会使得有些语句不执行或者重复执行。

6.5.2 条件结构

if…else结构

首先,看一个例子:

#判断条件
condition = 1if condition == 1:print("我是1")
else:print("我不是1")

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
我是1
>>>

以上就是python条件结构的一种,与之前的程序不同,程序由上至下执行的过程中,不是每一语句都执行了。通过运行结果可以看出,只有print("我是1")这条语句执行了。

控制这种执行顺序的,就是条件结构if...else...。下面我们来剖析一下这个结构:

if 关系运算语句:如果关系运算的结果为True,则执行这里的语句
else:如果关系运算的结果为False,则执行这里的语句

很好理解我就不过多解释了,但这里有3点需要强调

  1. 关系运算语句后的“:”,一定是英文的冒号,否则会有语法错误。

  2. “:”后一定要换行,换行后一定要缩进。python是一个很注意缩进的语言,这与其他语言不同。

  3. 缩进可以是一个Tab或者4个空格,但整个程序必须统一,要么全用4个空格,要么全用Tab。这里建议用4个空格。

还有一种特殊情况需要说明一下,就是有时候使用条件结构时,我们并没有想好全部的逻辑,比如下面程序:

#判断条件
condition = 1if condition == 1:print("我是1")
else:pass #此时还没想好else部分写什么,必须用一个pass代替

没有想好的部分一定要用pass来代替,否则会有语法错误。

if结构

上面讲了if...else...结构,但有时候我们不需要else部分,则else可以省略。比如下面的例子:

#判断条件
condition = 2if condition > 1 :print("我是1")
if…elif…else结构

有时候,对条件的判断不一定只有正反两个方面,可能存在多个分支。这时就要使用if...elif...else结构。如:

#判断条件
MyColor = "Red"if MyColor == "Red" :print("我是红色")
elif MyColor == "Green":print("我是绿色")
elif MyColor == "Black":print("我是黑色")
else:print("我是其他颜色")

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
我是红色
>>>

大家可以修改一下MyColor变量的值 ,看看不同的运行结果。

但上面的例子有一个特殊的地方,就是判断的条件都是等于,具有唯一性。等于“Red”就一定不是“Green”。但有些时候判断的条件可能发生重叠,比如:

#判断条件
MyNum = 5if MyNum > 1 :print("我大于1")
elif MyNum > 2:print("我大于2")
elif MyNum > 3:print("我大于3")
else:print("我是其他情况")

可以看出,MyNum = 5 符合条件结构中的三个,即大于1,也大于2,也大于3,此时程序会执行那一句呢?

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
我大于1
>>>

从运行结果可以看出是执行了第一个条件。if...elif...else结构总是执行第一个符合条件的代码,但这里要强调的是:虽然上面的程序python是允许的,但一个程序不应该有这样的情况发生,判断条件必须是彼此独立不重叠的,如果重叠了只能说明你的程序设计有问题。

最后,此结构中的else部分也可以省略,变为if...elif...这样的结构。

PS:有其他语言知识的可能会想到switch...case...结构,但python中不提供这种语法。

布尔运算

前面介绍的条件结构中,判断真假的关系运算语句只有一句话,比如value == 5,但实际上关系运算是可以组合的,组合的方式是通过布尔运算。关系运算语句的结果都是布尔值,只有True和False两种结果。布尔运算就是两个布尔值间的运算。

下面是布尔运算的运算符。

运算符 描述
and “且”运算,同真为真,比如 True and True = True,True and False = False
or “或”运算,有真为真,比如 False and False = False,True and False = True
not “非”运算,取相反值,比如 not True = False,not False = True

下面来看几个例子,都很好理解,就不过多说明了。

#判断条件
a = 5
b = 4if a == 5 and b == 4:print("且运算")if a == 5 or b == 3:print("或运算")if not a == 4:print("非运算")

运行结果

=============== RESTART: D:\project\project_python_learn\t1.py ===============
且运算
或运算
非运算
>>>

6.5.3 循环结构

For结构

For循环结构是最基本的循环结构。python中For循环是如下面例子的形式:

for item in [1,2,3,4,5]:print(item)

运行结果

=============== RESTART: D:\project\project_python_learn\t1.py ===============
1
2
3
4
5
>>>

这个例子中可以看出for循环的执行方式,首先选取[1,2,3,4,5]中的第一个值(也就是1)赋值给item,然后执行print(item),接着将第二个值(也就是2)赋值给item,再执行一次print(item),如此循环下去,直到[1,2,3,4,5]中所有的值都被选取一边,for循环结束。通过结果也可以看出print(item)被执行了5次。

这里再次强调一下语法问题,要注意“:”和缩进,否则会有语法错误。

另外,in ... :之间的部分不一定必须是一个列表(list),有时也可以是一个元组 (set),一个发生器(后文介绍),甚至是一个函数,只要这个函数的返回值是一个有限的可枚举的值。下面介绍一个在循环结构中常用的函数Range()。(函数的概念还没有介绍,但可以将range理解为像len,str一样的东西)

for item in range(1,5):print(item)

运行结果

=============== RESTART: D:\project\project_python_learn\t1.py ===============
1
2
3
4
>>>

可以看出,从效果上看range(1,5)相当于[1,2,3,4],但实际上两者有本质的不同,它实际上是一个发生器,这个后文会有介绍。

range的参数是这样定义的range(起始数,终止数,间隔=1),他会返回一个相当于范围[起始数,终止数)的可枚举的变量。间隔默认是1,也可以显示的指定间隔。下面举几个例子。

range(1,5) #相当于[1,2,3,4]range(1,6,2) #相当于[1,3,5]range(7,1,-1) #相当于[7,6,5,4,3,2]
break和continue

break关键字的作用是结束当前循环。比如下面的例子:

#判断给定list中是否存在大于100的数list = [1,2,5,101,7,8] #待检测的listisFind = False;for item in list:print(item)if item > 100:isFind = Truebreakprint(isFind)

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
1
2
5
101
True
>>>

上面的例子可以看出,当循环进行到item = 101 时,进入了条件判断语句if item > 100,然后遇到了break语句。break语句的作用就是结束循环,所以101后面的7,8就没有打印出来。大家可以删除例子中的break,看看打印结果又什么变化。

continue关键字的作用是跳过本次循环,直接进行下一个。比如下面的例子:

#打印出给定list中的偶数list = [1,2,6,5,10,101,7,8] #待检测的listfor item in list:if item % 2 != 0:continueprint(item)

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
2
6
10
8

首先,对于寻找偶数的问题,上面的例子并不是最好的方法,但它可以说明continue的作用。但item为奇数时,就会进入if item % 2 != 0的条件判断而遇到continue。continue的作用就是告诉程序,跳过此后的所有代码直接开始下一次循环。

For…else结构
while结构与while…else结构

6.6 函数

6.7 作用域

6.8 类

6.9 包与模块管理

6.10 站在巨人的肩膀上-引用第三方库

6.11 高级语法

附录

1 什么是保留字

所谓保留字,有的资料称为关键字。“保留”的意思就是Python语言已经对这些词的使用方法和含义进行了规定,作为程序员你就不能随便使用了。比如下面的程序:

as = 2+3 #使用as作为变量名
print(as) #将ans在屏幕(准确的说是PythonShell)中显示

当你执行这段代码时,会有如下效果:

Python编译器会告诉你有语法错误,而错误的原因正是因为as已经作为保留字,有独特的使用场景和方式,你就不能再将它用在变量名了。

那么,那些单词被Python当做保留字了呢?答案是很多,但你无需背下来,因为一些常见的保留字会随着你的编程经验的增长而逐渐加深印象,你会自然避免去使用。

另外,还有像上面例子中的查错机制。所以,编程时经常试运行一下,也可以帮你发现保留字的问题。

最后,选择一款有语法高亮的编辑器很有帮助,保留字会以明显的颜色显示,帮助你发现问题。

2 什么是二进制,十进制,十六进制

所谓进制,其实是一种进位的规则。我们最为熟悉的就是十进制就是逢十进一,二进制就是逢二进一,十六进制就是逢十六进一。

进制仅仅是数的一种表达形式,一个数无论以何种进制表达它的大小是不变的,所以不同进制间是可以互相转换的。

一个数之所以要有各种不同进制的表达,主要是为了更好的与现实情况接轨以及计算的方便。比如我们常用的时间是一种六十进制的形式,为什么1小时是60分钟,而不是10分钟或者100分钟。有兴趣的可以去看看天文发展史,选择1小时为60分钟是有客观需要的。

我们先来述说十进制,十进制有十个一位数:0,1,2,3,4,5,6,7,8,90,1,2,3,4,5,6,7,8,90,1,2,3,4,5,6,7,8,9

当我们想表达更大的数时,就发生了进位,变成两位数,比如10,11,1210,11,1210,11,12。

自然还有三位数,四位数等等,一个多位数可以表达为幂指数相加的形式,如:
342=3∗102+4∗101+2∗100342=3*10^2+4*10^1+2*10^0 342=3∗102+4∗101+2∗100
同理,二进制只有两个一位数:0,10,10,1。

依据逢二进一的规则,十进制的2在二进制中就是10,十进制的3在二进制中就是11。

我们可以通过幂指数的形式实现二进制向十进制的转换,如:
1111=1∗23+1∗22+1∗21+1∗20=151111=1*2^3+1*2^2+1*2^1+1*2^0=15 1111=1∗23+1∗22+1∗21+1∗20=15
最后,十六进制的一位数有十六个:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F。

其中,A,B,C,D,E,FA,B,C,D,E,FA,B,C,D,E,F分别表示十进制中的10,11,12,13,14,1510,11,12,13,14,1510,11,12,13,14,15。并且不区分大小写。

依据逢十六进一的规则,十进制的16就是10,十进制的17就是11,十进制的24是18,十进制的31是1F。

我们依然可以利用幂指数的形式实现十六进制向十进制的转换,如:
1F=1∗161+15=311F=1*16^1+15=31 1F=1∗161+15=31

如何在python中表达十进制、二进制和十六进制数

我们直接看程序。

a = 10     #python中十进制的表达与我们熟悉的方式相同b = 0b1010 #python中以“0b”开头的数字会被认为是二进制数c = 0xA    #python中以“0x”开头的数字会被认为是十六进制数#通过打印结果可以看到,虽然表达形式不同,但他们本质上是相等的
print(a == b)
print(b == c)

运行结果:

=============== RESTART: D:\project\project_python_learn\t1.py ===============
True
True
>>>

3 什么是位,什么是字节

计算机只能识别0和1。计算机领域将只能存储一个0或一个1所需要的“空间”称为1位,单位是bit。

如果一个“空间”有8位,我们称这个“空间”为一个字节,单位为byte。

显然,1byte=8bit1byte = 8bit1byte=8bit

延申一下还有 1024byte=1K1024byte = 1K1024byte=1K,1024K=1M1024K=1M1024K=1M,1024M=1G1024M=1G1024M=1G…

那么,用1byte1byte1byte的“空间”,可以表示的最大的数是几呢?我们不妨计算一下:

1byte1byte1byte有8bit8bit8bit,所以最大的数,用二进制表示是11111111,换算为十进制就是255。

反过来,存储345需要多少个字节呢?

我们将345换算为二进制,即0001 01010 1001,共12位,所以是1.5byte1.5byte1.5byte,但计算在存储数据时都是以bytebytebyte为单位取整,所以345在计算机中存储至少要占用2byte2byte2byte。

细心的人会发现,以上的方法只能存储正整数,负数怎么办?小数怎么办?

这就又要介绍存储编码的知识,涉及到什么是补码,什么是IEEE浮点数编码等知识,会在其他章节介绍。

4 如何表示负数,什么是补码

前面我们提到1Byte的空间最大可以表示的数是255,但这结论有一个前提,我们默认数的存储形式与二进制数的表达形式是相同的。

换句话说,如果我们将一个数直接以他的二进制数形式存储在空间中,我们称这种存储采用了原码

采用原码存储的好处是直观,但带来的问题是原码形式无法表达负数。

为了在计算机中存储负数,科学家们又发明了数的补码形式。

一个数的补码是这么规定:

  1. 无论一个数存储要多少个字节,最高位为符号位,1表示负数,0表示整数,后面的位表示数值。
  2. 如果是正数,则最高位为0,后面的数值位直接用正数的原码形式填充,即得到正数的补码形式。
  3. 如果是负数,首先得到其绝对值的原码,然后将其绝对值的原码按位取反再加一,得到负数的补码形式。

下面我们来分别介绍一下这几条:

第一条:

假设有如下的一个数的补码:100100101011010010010101101001001010110,虽然我们很难一眼看出它表示的是哪个数,但由于最高位(左数第一位)是1,所以我们可以知道这是一个负数。同理,010101010001010101010001010101010001就是一个正数。

第二条:

假设有一个数的补码为:01010110。首先,它的最高位是0,所以是一个正数,它的数值位是1010110,我们知道正数的补码的数值位就是它的原码,1010110是86的二进制形式,所以 01010110表示的是正数86。

第三条:

那么-86的补码是什么呢?依据第三条规则,我们首先要得到其绝对值,即86的原码,是01010110。然后按照“按位取反再加一”规则计算,得10101010。所以10101010是-86的补码。

有兴趣可以试着计算一下,以补码的形式,1Byte能存储的数据范围,答案是-128到127 。

好懂的Python教程相关推荐

  1. 给老婆写个Python教程

    作者 | 水风 来源 | 水风知乎问答 如何挑战百万年薪的人工智能! https://edu.csdn.net/topic/ai30?utm_source=csdn_bw 什么是code code就是 ...

  2. 【python教程入门学习】Python实现自动玩贪吃蛇程序

    这篇文章主要介绍了通过Python实现的简易的自动玩贪吃蛇游戏的小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学一学 实现效果 先看看效果 这比我手动的快多了,而且是单机的,自动玩没惹 ...

  3. OpenCV Python教程(2、图像元素的访问、通道分离与合并)

    OpenCV Python教程之图像元素的访问.通道分离与合并 转载请详细注明原作者及出处,谢谢! 访问像素 像素的访问和访问numpy中ndarray的方法完全一样,灰度图为: [python] v ...

  4. 廖的python教程_廖雪峰的Python3.x教程.pdf

    目录 Python教程 Python简介 安装Python Python解释器 第一个Python程序 使用文本编辑器 Python代码运行助手 输入和输出 源码 learning.py Python ...

  5. python教程app下载地址_python教程

    python教程它是一个移动编程学习应用程序,可以为学习编程的用户提供高级学习工具,借助该软件,用户可以轻松获得各个阶段的培训资料,并且大量高质量的培训视频简化并简化了用户培训,有兴趣的朋友可以轻松下 ...

  6. python是什么系统_最齐全、最系统的python教程

    python教程(后面有彩蛋) python教程目录 学python都用来干嘛的? 主要就是"简单啊"."收入高啊"."人生苦短,我用Python&q ...

  7. python操作excel-python操作excel(内附python教程分享)

    今天学习了下xlwings这个库,目的是为了让计算机自动化操作excel表,当某天需要做一些很繁琐的事情,就可以派上用场啦. python操作excel(内附python教程分享) 基本对象 网上刮来 ...

  8. python 教程 网盘-python教程网盘

    广告关闭 腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元! 解释器不会一次把整个程序转译出来,只像一位"中间人",每次运行 ...

  9. python画代码-Python教程_Python画Mandelbrot集 代码

    Python教程_Python画Mandelbrot集 代码 作者:Comet 来源: 课课家 www.kokojia.com点击数:278发布时间:2015-06-19 11:17:19 曼德勃罗集 ...

最新文章

  1. 桌面环境选择_Ubuntu 18.04 桌面环境初体验
  2. linux 环境安装及学习
  3. HTML的定义和特点,【HTML】复习笔记(一)初识HTML
  4. 今日看了一下广告收入,心里拔凉拔凉的。
  5. java饼状图获取数据集_HighChars3D饼图(从后台获取数据)
  6. 基于Bayes和KNN的newsgroup 18828文本分类器的Python实现
  7. STM32中RTC唤醒停止模式
  8. 【盘点】电影中八大邪恶的超级计算机
  9. 我来告诉你spyder打不开在哪里看找问题
  10. 58 非常酷的单页网站设计灵感
  11. 密码学的安全性浅析-4
  12. Kubernetes多运营商云服务器部署(kubeadm+ipvs+flannel)
  13. html5滑动删除置顶,js实现移动端向左滑动删除效果
  14. 发展科技到底有什么用,转NASA专家给一位修女的一封信
  15. 字符串分割split()方法:将一个字符串通过指定的分隔符分割成若干子串
  16. flink onTimer定时器实现定时需求
  17. 房产测量程序lisp_房产测绘内业数据处理方法及软件应用
  18. 学生类定义(类和对象)
  19. win10 ping命令与telnet命令使用详解
  20. 【渝粤教育】广东开放大学 薪酬与福利管理 形成性考核 (41)

热门文章

  1. Automatic NUMA balancing in RHEL7
  2. 微信扫描二维码登录网页原理
  3. 谈一谈神奇的ShadowDOM
  4. WIN10和Ubuntu共享蓝牙4.0连接配对,鼠标键盘等,罗技M720,小米鼠标
  5. 老年人腰扭伤如何治疗
  6. QQ群文件下载速度慢-解决得得得得办法
  7. 3dsMax里GLTF插件的安装和使用
  8. Python之单引号、双引号、三单引号、三双引号
  9. 基于深度学习的犬种识别软件(YOLOv5清新界面版,Python代码)
  10. 两个小程序(刷人气)