Python基础
本章我们将实际学习Python的基础知识,介绍Python的基本操作符、变量的命名与使用、Python的基本数据类型。对于每一个内容,我将通过实例展示、解析其含义并进行延伸。复杂的代码总是可以拆解为小块基本操作的集合,Python易读易懂的语言特性让这一概念更为形象,希望读者在学习的初始就养成写良好的代码的习惯,我会贯穿整本书帮助大家不仅学会写Python代码、分析数据,而且写出的代码优良易懂。
你好啊,世界!
在极大多数的编程学习书籍或者教学中,第一个代码实现是向屏幕输出“Hello World!”,作为一本中文书籍,我们先一起来实现输出它的中译版本“你好啊,世界!”。
首先,我们打开软件nteract
,或者使用jupyter notebook
创建一个笔记本。没有进行软件安装和配置的读者请阅读第一章介绍与学习准备。
在软件输入框中键入print('你好啊,世界')
,然后摁下快捷键Ctrl
+Enter
(Windows,苹果将Ctrl
换为Cmd
键即可),输出效果如下:
你也可以点击输入框右上角的三角运行标记。
我们的第一个程序完成了。是不是很简单?
等等,我还没有解释这句代码是什么意思。
这句代码总共16个字符,其中7个字符是我们认识的“你好啊,世界!”,其他9个字符是我们暂时还不理解的print
+()
+''
。它们是什么意思呢?
print
是Python提供的一个命令,它默认可以向屏幕输出用户(我们)定义的字符(串),依赖()
来区分我们输入的内容什么是它要处理的对象,而这个对象就是由单引号''
括起来的文字。
为了查看我的解释是否正确,我们向输入框键入以下内容进行测试:
print('你好啊,世界!)
print('你好啊,世界')!
它们的结果如下图:
你好啊,世界 错误写法很显然,我们的这两句代码存在问题,所以都出现了“SyntaxError”语法错误。
可见,遵守Python的规则——语法很重要,我们后续会逐步对它进行学习。除此之外,我也希望读者能养成探索的习惯,在学习本书乃或是其他书籍时理解内容的最好方式是动手实践并进行思考,并将思考又进行实践。没有哪一本书籍不存在过时或者错误,编程也从来不是一门能靠死记硬背学会的技术,动手给书籍“找碴”的同时收获对知识的掌握和理解,何乐而不为呢?
notebook初使用
在上一个图中我们看到代码和对应的输出结果分成了在nteract软件界面中分成了一块一块,每一块都是一个相对独立的代码单元,包含我们键入的指令(代码)和相应的输出,我们称之为单元格(Cell)。
单元格单元格中呈现的所有信息都会被存储为jupyter(朱庇特)笔记本,它以特定的.ipynb
作为文件名后缀。nteract软件保存的jupyter笔记本与基于浏览器的jupyter notebook创建/保存的笔记本是完全一致的,只是以两种不同的外形展现出来。因此读者完全可以将用nteract创建的笔记本上传到网络上(比如开源仓库GitHub)用jupyter的nbviewer进行查看,或者上传保存到微软的Jupyter分析平台(https://notebooks.azure.com/)查阅、编辑和分享;同样地,读者也可以将网络上优秀的jupyter笔记本下载到本地,使用nteract打开,进行分析的重复实现与学习。
nteract软件除了现在界面语言是英文显示,其他效果都做的非常好。我们可以像平常使用Windows软件一样,用鼠标点点点对单元格进行操作,最常见的运行、删除都以图标的方式显示在单元格的右上角,使用起来很方便。喜欢快捷键的键盘侠们可以通过菜单栏的各个选项了解快捷键的使用。
在运行代码时,最常见的两个快捷键是Ctrl+Enter
以及Shift+Enter
键,前者运行当前单元格;后者先运行单元格,然后新建一个单元格。相对而言,后者更为便利。
另外未曾提到的内容是每个单元格左侧都有[ ]
标记,当代码运行后,中间会出现数字,标记了单元格运行的次序。
首先,Python是个计算器
在完成第一个Python代码后,对数据分析感兴趣的你们是不是想知道Python要怎样实现数据的计算?先别急,让我们从最简单的计算开始,看看Python怎么完成进行数值的加减乘除任务,成为手头的计算神器。
我们来看几个足够简单的任务,嘿嘿
只关于1与操作符的计算任务上图中只有数字1和运算操作符,可见+
,-
,*
,/
分别对应我们日常的加减乘除操作。等等,1 / 1
的结果怎么是1.0
,它不应该是1
吗?
注意,除法分为两种,一种是整除,另一种自然是非整除了。Python有两个符号对应这两个操作,除了我们在图中看到的/
符号,//
会进行整除操作。除不尽时自然有余数,Python中%
符可以进行求余操作。
Python比较完整的算术操作汇总如下:
3 + 2 # 加法
3 / 2 # 浮点数除法
3 // 2 # 整除
3 * 2 # 乘法
3 ** 2 # 指数
3 % 2 # 求余
abs(a) # 绝对值
代码约定
我通过上面的例子向读者简单介绍了如何利用nteract创建和使用jupyter notebook并用它输入Python代码。为了提高代码书写和利用的效率,我接下来使用文本的形式输入代码和展示结果。
比如前面关于1的几个运算操作,我会用
In [3]: 1 + 1
Out[3]: 2
In [4]: 1 - 1
Out[4]: 0
In [5]: 1 * 1
Out[5]: 1
In [6]: 1 / 1
Out[6]: 1.0
来替换
注意: 代码左侧的[3]、[4]标定了Python运行代码的次序,这并不是指必须在[3]运行后才能运行[4]。我会在后面的例子中稍加说明。
计算你的身体质量指数
我们已经学会如何使用Python进行简单的计算,现在我们把所学用来做件更有意义的事情——计算自己的身体质量指数。
身体质量指数(BMI)是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准,相信不少读者在进行体检时都会测量这个指标,它是用体重公斤数除以身高米数平方得出的数字。也就是说,只要知道自己的身高和体重,就可以自己计算BMI。
比如作为作者的我,身高182cm,体重70kg左右,所以BMI指数为:
In [11]: 70 / 1.82 ** 2
Out[11]: 21.132713440405748
唔,还属于正常范围。你也自己试试吧。
我的BMI指数可是,当我把它发给我的朋友时,发现朋友完全不懂这是什么意思,怎么办?
解决的办法是给代码加上中文/英文注释,这样朋友就能够通过语言来理解这些数字符号所代表的含义。在Python中,使用符号#
可以引导一行注释,因此上述添加注释后的代码为:
In [12]: 70 / 1.82 ** 2 # 计算我的BMI指数
Out[12]: 21.132713440405748
注释也可以写在运行代码的前一行,但不能写在前面,不然代码自身也会被当作注释而无法运行:
In [13]: # 计算我的BMI指数
In [14]: 70 / 1.82 ** 2
Out[14]: 21.132713440405748
In [15]: # 计算我的BMI指数 70 / 1.82 ** 2
[13]和[15]没有对应的
out
标记看起来这两行代码并没有被Python执行,因而没有相应的输出结果。实际上,Python会在运行前检查输入的语句块,发现它是以#
开头的语句,所以跳过去了(不执行);如果代码存在语法错误,Python会停止运行并给出相应的错误和提示。
比如:In [16]: 计算我的BMI指数 70 / 1.82 ** 2 File "<ipython-input-16-b7d966d13e1f>", line 1 计算我的BMI指数 70 / 1.82 ** 2 ^ SyntaxError: invalid syntax
为代码添加注释是一个代表专业性的好习惯,它使得代码便于追溯并且提高可读性。再厉害的程序员也会在一年之后忘记之前写的代码细节,好的代码注释能够帮助自己或他人快速理解和重用程序或代码块,提升编程的效率和能力,请读者务必谨记并用于实践。
变量
变量的力量
仅仅使用字面意义上的70
、1.82
这些数字很快就会引发烦恼,比如当我们与朋友的BMI指数进行比较时,会很快对键入数字感到不厌其烦,甚至对编写程序失去兴趣。另外,一旦操作涉及较多的运算符,它所展现的意思已经不那么明显了(比如下面[12]与[10]和[11]作比较)。
In [9]: # 与朋友比较BMI指数
In [10]: 70 / 1.82 ** 2
Out[10]: 21.132713440405748
In [11]: 48 / 1.64 ** 2
Out[11]: 17.846519928613922
In [12]: 70 / 1.82 ** 2 - 48 / 1.64 ** 2
Out[12]: 3.2861935117918257
我们需要一种既可以储存信息,又可以对它们进行操作的方法。这正是变量存在的意义。变量是一种这样的东西——它们的值可以变化,因而你可以使用变量存储任何东西,像身高、体重、今天星期几、天气、手机号码等等。变量本身只是你的计算机中存储信息的一部分内存,为了访问它存储的信息,我们需要给变量命名。而将信息(数据)存为变量的操作,称为赋值。
例如我将自己的身高和体重存储为变量:
In [13]: height = 1.82
In [14]: weight = 70
=
是赋值操作符,新手需要注意它不是相等!height = 1.82
语义为:将数字1.82赋值给height变量。我会在后面介绍运算符操作时详细讲解。
我们可以使用print()
函数或者直接键入变量名输出变量保存的信息:
In [15]: print(height)
Out[15]: 1.82
In [16]: print(weight)
Out[16]: 70
In [17]: height
Out[17]: 1.82
In [18]: weight
Out[18]: 70
因而与朋友比较BMI指数可以写为:
In [19]: myBMI = 70 / 1.82 ** 2 # 我的BMI指数
In [20]: friendBMI = 48 / 1.64 ** 2 # 朋友的BMI指数
In [21]: myBMI - friendBMI
Out[21]: 3.2861935117918257
变量的命名
变量的命名需要遵循一定的规则:
- 第一个字符必须是字母表中的字母(大写或小写)或者一个下划线
_
。 - 其他部分可以由字母(大写或小写)、下划线
_
或数字(0-9)组成。 - 名字是对大小写敏感的。例如,
myname
和myName
不是一个标识符。注意前者中的小写n
和后者中的大写N
。
i
、__my_name
、name_23
和a1b2_c3
是有效的名字;2things
、this is spaced out
和my-name
是无效的名字。
举个例子:
IIn [22]: __myName = "ShixiangWang"
In [23]: my-name = "ShixiangWang"
File "<ipython-input-23-1b106abe1308>", line 1
my-name = "ShixiangWang"
^
SyntaxError: can't assign to operator
给变量命名是一个古老的问题,也是编程的基础。新手往往在处理简单问题时会选择a
,b
,c
这样的名字,如果有多组变量,可能会使用a1
,a2
,a3
...这样的方式命名。这样都是非常不可取的,变量的名字应该具有非常清晰的含义。变量的命名和取名字一样重要,甚至更重要。对于我们现实中的事物,比如小狗,你给小狗取一个好名字固然重要,但它并不会改变小狗本身。但变量不是这样的,变量和变量名本质上是同一件事物,因此,变量的好与坏就在很大程度上取决于它的命名的好与坏。
好的变量名的注意事项
- 最重要的考虑事项是,该名字要完全、准确地描述出该变量所代表的事物;
- 一个好名字通常表达的是“什么”(what),而不是“如何”(how),一般而言,如果一个名字反映了计算的某些方面而不是问题本身,那么它反映的就是“how”,而非“what”,譬如,同样一个命名,calcVal比sum更偏向于“how”,不提倡;
- 最适合的名字长度:10-16字符之间,但更重要的是长度和清晰度之间的平衡,通常较短的名称适用于局部变量或者循环变量,较长的名字适用于很少用到的变量或者全局变量(全局变量与局部变量我会在后面的章节介绍);
- 变量中的计算值限定词:表示计算结果的词:总额、平均值、最大值、等等,如果你要用类似于Total、Sum、Average、Max、Min、Record这样的限定词来修饰某个名字,那么请把限定词加到名字的最后。例如revenueTotal、expenseAverage等等,这样做的目的是将为这一变量赋予主要含义的部分放到最前面,提高可读性。
以上是对《代码大全》中“如何定义一个好的变量名”部分的简单归纳,读者在学习之初并不一定能完全理解和熟练使用它,但需要记住一个思想:给变量命名是一个非常重要的事情。在行动上,每次对变量命名后应当有意识地思考一下该名字是否能准确地描述出变量所代表的事物,如果不能,请重新想一个新的名字,如果你觉得自己词穷,CODELF(http://unbug.github.io/codelf/)将会是一个很好的帮手。
推荐阅读
Python基本数据类型
“算法+数据结构=程序”,这是1984年图灵奖的获得者Niklaus E. Wirth阐述的一个经典观点。数据的结构常常由多个数据类型组成,其中数字、字符串与布尔值是Python基本的内置数据类型,它们是数据表达、存储的基础。而其他Python中常见的数据类型,比如下一章会学习和使用的列表,是基于这三种数据类型的组合构建的新类型。
数字
在 Python 中有 4 种类型的数——整数、长整数、浮点数和复数。
- 整数和我们数学中是对应的,像1,2,3,4,...
- 长整数不过是大一些的整数。
- 3.23和5E-4是浮点数的例子。E标记表示10的幂,是一种科学计数法。在这里,5E-4表示5 * 10-4,即0.0005。
- (-5+4j)和(2.3-4.6j)是复数的例子。
字符串
字符串是字符的序列,基本上就是一串字母、数字与符号的组合。
下面是字符串的使用方法:
-
我们可以用单引号
''
指示字符串,就如同'Quote me on this'这样。所有的空白,包括空格和制表符都照原样保留。 -
我们也可以使用双引号
""
来指定字符串,它的方式与单引号中的字符串的使用完全相同,例如"What's your name?"。 -
我们利用三引号
'''
或"""
可以指示一个多行的字符串。你可以在三引号中自由的使用单引号和双引号。
例如:'''This is a multi-line string. This is the first line. This is the second line. "What's your name?," I asked. He said "Bond, James Bond." '''
转义符
假设我们想要在一个字符串中包含一个单引号('),那么该怎么指示这个字符串?例如,这个字符串是What's your name?
。'What's your name?'肯定是错误的使用方式,因为Python 会弄不明白这个字符串从何处开始,何处结束。我们需要告诉Python单引号不是字符串的结尾。这可以通过转义符来实现完成。我们可以用\'
来指示单引号——注意这个反斜杠,因而把字符串表示为'What's your name?'。
另一个方法是单双引号嵌套,"What's your name?",它将单引号'
嵌入双引号中,Python会发现双引号是字符串的起止符号,因而单引号会被正确的解析。类似地,要在双引号字符串中使用双引号本身的时候,也可以借助于转义符。另外,我们可以用转义符\
来指示反斜杠本身。
In [26]: 'What's your name?' # 错误的表示方法
File "<ipython-input-26-dff8324f3597>", line 1
'What's your name?' # 错误的表示方法
^
SyntaxError: invalid syntax
In [27]: 'What\'s your name?' # 使用\对字符串中的单引号进行转义
Out[27]: "What's your name?"
In [28]: "What\'s your name?" # 将单引号嵌入双引号中
Out[28]: "What's your name?"
值得注意的是,在一个字符串行末,单独一个反斜杠表示字符串在下一行继续,而不是开始一个新的行。例如:
"This is the first sentence.\
This is the second sentence."
等价于"This is the first sentence. This is the second sentence."
自然字符串
如果我们想要表示某些不需要如转义符那样特别处理的字符串,那么我们可以指定一个自然字符串。自然字符串通过给字符串加上前缀r或R来指定。
例如r"Newlines are indicated by \n",其中\n
时文本的换行符,请读者理解下面结果的不同:
In [35]: "Newlines are indicated by \n"
Out[35]: 'Newlines are indicated by \n'
In [36]: r"Newlines are indicated by \n"
Out[36]: 'Newlines are indicated by \\n'
In [37]: print(r"Newlines are indicated by \n")
Out[37]: Newlines are indicated by \n
In [38]: print("Newlines are indicated by \n")
Out[38]: Newlines are indicated by
# 此处输出一个空行
Unicode 字符串
Unicode是书写国际文本的标准方法(也称为万国码)。Python中我们只需要在字符串前加上前缀u或U就可以处理Unicode字符串。例如,u"This is a Unicode string."。需要记住,在我们知道文本中含有非英语写的文本时,最好使用Unicode字符串。
布尔值
任何一门编程语言都会存在布尔类型,用来表示“真/假”。这不仅仅是因为计算机的基础是二进制,而且我们人类对于事物的基本判断也是二元的,往往不是“真”就是“假”,不是“美”就是“丑”。
在Python中,这两个值有固定的表示:True
代表真,False
代表假。注意,Python是大小写敏感的语言,false
不等同于False
。
猜猜数据类型
我们已经学习了Python的三个基本数据类型,但在实际的使用过程中,我们该如何知道一个变量属于哪一种类型呢?
比如我现在有赋值了的4个变量:
In [45]: type1 = 1
In [46]: type2 = 1.0
In [47]: type3 = "1"
In [48]: type4 = True
我们可以使用type()
函数查看该变量的数据类型:
In [49]: type(type1)
Out[49]: int
In [50]: type(type2)
Out[50]: float
In [51]: type(type3)
Out[51]: str
In [52]: type(type4)
Out[52]: bool
这里int
、str
与bool
分别是integer(整数)、string(字符串)与boolean(布尔值)的缩写。
数据运算
上一节我讲述了Python几个基本的数据类型,但除了数学运算,我还没有实际演示其他数据类型是如何操作的,以及这些基本的数据类型怎么相互转换和配合使用。
我们已经知道数字1+1
的结果是它们的和,字符'1'+'1'
的结果又是什么呢?
In [2]: '1' + '1'
Out[2]: '11'
+
号可以将两个字符粘连起来!如果你想尝试下减号,你可能会有点失望——它并不能从一个字符串中去除另一个字符:
In [3]: '1' - '1'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-3f89fba82f3e> in <module>()
----> 1 '1' - '1'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
可为什么+号又能求数字的和,又能粘连字符?这我们必须提到一个叫泛型的概念:它就像一个黑箱子,比如我们这里使用的+
号,我们只能看到外表标记了一个+
号,但它会根据不同的输入数据类型(像数字或字符)执行不同的命令。
我们现在知道使用type
函数可以判断'1'
是字符1还是数字1。但我们该怎么将字符1变成数字1呢?这需要我们将str
转换为int
类型,Python恰好有这个名字的函数可以完成这个操作。
In [8]: type('1')
Out[8]: str
In [9]: type(int('1'))
Out[9]: int
除此之外,读者需要注意字符串与数字不能够进行+
操作,它必须将一方转换为另一方类型,不然会抛出语法错误:
In [10]: "我的语文和数学成绩之和是 " + 199
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-17fa10d93550> in <module>()
----> 1 "我的语文和数学成绩之和是 " + 199
TypeError: must be str, not int
In [11]: "我的语文和数学成绩之和是 " + str(199)
Out[11]: '我的语文和数学成绩之和是 199'
这里使用str()
将数字199
强制转换为字符,相似的函数有int()
,float()
以及bool()
。
Python常用的内置操作符包括算术操作符、字符串操作符、比较操作符与布尔逻辑操作几类,我将其操作汇总如下,并给出一个简单的实例,请读者自行运行例子并体会操作结果与及类型。
算术操作符:
9 + 2 # 加
9 - 2 # 减
9 * 2 # 乘
9 / 2 # 除(浮点输出)
9 //2 # 整除
9 % 2 # 求余
9 **2 # 幂
字符串操作符:
'这是一个' + '字符串' # 字符串粘连
'这是一个字符串' * 5 # 字符串重复
比较操作符:
5 == 4 # 等于
5 > 4 # 大于
5 < 4 # 小于
5 != 4 # 不等于
5 >= 4 # 大于或等于
5 <= 4 # 小于或等于
布尔操作逻辑:
True and True # 逻辑与
True or False # 逻辑或
not False # 逻辑非
推荐阅读
本章完。下一章节,我会详细介绍Python列表的使用,欢迎大家订阅关注。
另外,如果大家对本章内容有疑问与建议,欢迎在下方留言:)
网友评论
老司机?