1 相关工具 1.1 IPython
IPython
是一种基于Python的交互式解释器。相较于原生的Python交互式环境,IPython
提供了更为强大的编辑和交互功能。可以通过Python的包管理工具pip安装IPython
,具体的操作如下所示。
安装成功后,可以通过下面的ipython
命令启动IPython
,如下图所示。
2 语法 2.1 类型转换 可以使用Python中内置的函数对变量类型进行转换:
int()
:将一个数值或字符串转换成整数,可以指定进制。
float()
:将一个字符串转换成浮点数。
str()
:将指定的对象转换成字符串形式,可以指定编码。
chr()
:将整数转换成该编码对应的字符串(一个字符)。
ord()
:将字符串(一个字符)转换成对应的编码(整数)。
其中注意一下chr
和ord
,这两个之前没用过。
下面的代码通过键盘输入两个整数来实现对两个整数的算术运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 """ 使用input()函数获取键盘输入(字符串) 使用int()函数将输入的字符串转换成整数 使用print()函数输出带占位符的字符串 """ a = int (input ('a = ' )) b = int (input ('b = ' )) print ('%d + %d = %d' % (a, b, a + b))print ('%d - %d = %d' % (a, b, a - b))print ('%d * %d = %d' % (a, b, a * b))print ('%d / %d = %f' % (a, b, a / b))print ('%d // %d = %d' % (a, b, a // b))print ('%d %% %d = %d' % (a, b, a % b))print ('%d ** %d = %d' % (a, b, a ** b))
说明 :上面的print函数中输出的字符串使用了占位符语法,其中%d
是整数的占位符,%f
是小数的占位符,%%
表示百分号(因为百分号代表了占位符,所以带占位符的字符串中要表示百分号必须写成%%
),字符串之后的%
后面跟的变量值会替换掉占位符然后输出到终端中,运行上面的程序,看看程序执行结果就明白啦。
2.2 for-in循环 如果明确的知道循环执行的次数或者要对一个容器进行迭代(后面会讲到),那么我们推荐使用for-in
循环,例如下面代码中计算1~100求和的结果($\displaystyle \sum \limits_{n=1}^{100}n$)。
1 2 3 4 5 6 7 8 """ 用for循环实现1~100求和 """ sum = 0 for x in range (101 ): sum += x print (sum )
需要说明的是上面代码中的range(1, 101)
可以用来构造一个从1到100的范围,当我们把这样一个范围放到for-in
循环中,就可以通过前面的循环变量x
依次取出从1到100的整数。当然,range
的用法非常灵活,下面给出了一个例子:
range(101)
:可以用来产生0到100范围的整数,需要注意的是取不到101。
range(1, 101)
:可以用来产生1到100范围的整数,相当于前面是闭区间后面是开区间。
range(1, 101, 2)
:可以用来产生1到100的奇数,其中2是步长,即每次数值递增的值。
range(100, 0, -2)
:可以用来产生100到1的偶数,其中-2是步长,即每次数字递减的值。
知道了这一点,我们可以用下面的代码来实现1~100之间的偶数求和。
1 2 3 4 5 6 7 8 """ 用for循环实现1~100之间的偶数求和 """ sum = 0 for x in range (2 , 101 , 2 ): sum += x print (sum )
2.3 函数可变参数 在不确定参数个数的时候,我们可以使用可变参数,代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def add (*args ): total = 0 for val in args: total += val return total print (add())print (add(1 ))print (add(1 , 2 ))print (add(1 , 2 , 3 ))print (add(1 , 3 , 5 , 7 , 9 ))
3 数据结构 3.1 字符串 Python为字符串类型提供了非常丰富的运算符,我们可以使用+
运算符来实现字符串的拼接,可以使用*
运算符来重复一个字符串的内容,可以使用in
和not in
来判断一个字符串是否包含另外一个字符串(成员运算),我们也可以用[]
和[:]
运算符从字符串取出某个字符或某些字符(切片运算),代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 s1 = 'hello ' * 3 print (s1) s2 = 'world' s1 += s2 print (s1) print ('ll' in s1) print ('good' in s1) str2 = 'abc123456' print (str2[2 ]) print (str2[2 :5 ]) print (str2[2 :]) print (str2[2 ::2 ]) print (str2[::2 ]) print (str2[::-1 ]) print (str2[-3 :-1 ])
在Python中,我们还可以通过一系列的方法来完成对字符串的处理,代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 str1 = 'hello, world!' print (len (str1)) print (str1.capitalize()) print (str1.title()) print (str1.upper()) print (str1.find('or' )) print (str1.find('shit' )) print (str1.startswith('He' )) print (str1.startswith('hel' )) print (str1.endswith('!' )) print (str1.center(50 , '*' ))print (str1.rjust(50 , ' ' ))str2 = 'abc123456' print (str2.isdigit()) print (str2.isalpha()) print (str2.isalnum()) str3 = ' jackfrued@126.com ' print (str3)print (str3.strip())
Python 3.6以后,格式化字符串还有更为简洁的书写方式,就是在字符串前加上字母f
,我们可以使用下面的语法糖来简化上面的代码。
1 2 a, b = 5 , 10 print (f'{a} * {b} = {a * b} ' )
除了字符串,Python还内置了多种类型的数据结构,如果要在程序中保存和操作数据,绝大多数时候可以利用现有的数据结构来实现,最常用的包括列表、元组、集合和字典。
3.2 列表 列表(list
)是一种结构化的、非标量类型,它是值的有序序列,每个值都可以通过索引进行标识,定义列表可以将列表的元素放在[]
中,多个元素用,
进行分隔,可以使用for
循环对列表元素进行遍历,也可以使用[]
或[:]
运算符取出列表中的一个或多个元素。
下面的代码演示了如何定义列表、如何遍历列表以及列表的下标运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 list1 = [1 , 3 , 5 , 7 , 100 ] print (list1) list2 = ['hello' ] * 3 print (list2) print (len (list1)) print (list1[0 ]) print (list1[4 ]) print (list1[-1 ]) print (list1[-3 ]) list1[2 ] = 300 print (list1) for index in range (len (list1)): print (list1[index]) for elem in list1: print (elem) for index, elem in enumerate (list1): print (index, elem)
下面的代码演示了如何向列表中添加元素以及如何从列表中移除元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 list1 = [1 , 3 , 5 , 7 , 100 ] list1.append(200 ) list1.insert(1 , 400 ) list1 += [1000 , 2000 ] print (list1) print (len (list1)) if 3 in list1: list1.remove(3 ) if 1234 in list1: list1.remove(1234 ) print (list1) list1.pop(0 ) list1.pop(len (list1) - 1 ) print (list1) list1.clear() print (list1)
和字符串一样,列表也可以做切片操作,通过切片操作我们可以实现对列表的复制或者将列表中的一部分取出来创建出新的列表,代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 fruits = ['grape' , 'apple' , 'strawberry' , 'waxberry' ] fruits += ['pitaya' , 'pear' , 'mango' ] fruits2 = fruits[1 :4 ] print (fruits2) fruits3 = fruits[:] print (fruits3) fruits4 = fruits[-3 :-1 ] print (fruits4) fruits5 = fruits[::-1 ] print (fruits5)
下面的代码实现了对列表的排序操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 list1 = ['orange' , 'apple' , 'zoo' , 'internationalization' , 'blueberry' ] list2 = sorted (list1) list3 = sorted (list1, reverse=True ) list4 = sorted (list1, key=len ) print (list1)print (list2)print (list3)print (list4)list1.sort(reverse=True ) print (list1)
3.3 生成式和生成器 我们还可以使用列表的生成式语法来创建列表,代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 f = [x for x in range (1 , 10 )] print (f)f = [x + y for x in 'ABCDE' for y in '1234567' ] print (f)f = [x ** 2 for x in range (1 , 1000 )] print (sys.getsizeof(f)) print (f)f = (x ** 2 for x in range (1 , 1000 )) print (sys.getsizeof(f)) print (f)for val in f: print (val)
3.4 yeild
除了上面提到的生成器语法,Python中还有另外一种定义生成器的方式,就是通过yield
关键字将一个普通函数改造成生成器函数。下面的代码演示了如何实现一个生成斐波拉切数列 的生成器。所谓斐波拉切数列可以通过下面递归 的方法来进行定义:
1 2 3 4 5 6 7 8 9 10 11 12 def fib (n ): a, b = 0 , 1 for _ in range (n): a, b = b, a + b yield a def main (): for val in fib(20 ): print (val) if __name__ == '__main__' : main()
3.5 元组 Python中的元组与列表类似也是一种容器数据类型,可以用一个变量(对象)来存储多个数据,不同之处在于元组的元素不能修改 ,在前面的代码中我们已经不止一次使用过元组了。顾名思义,我们把多个元素组合到一起就形成了一个元组,所以它和列表一样可以保存多条数据。下面的代码演示了如何定义和使用元组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 t = ('骆昊' , 38 , True , '四川成都' ) print (t)print (t[0 ])print (t[3 ])for member in t: print (member) t = ('王大锤' , 20 , True , '云南昆明' ) print (t)person = list (t) print (person)person[0 ] = '李小龙' person[1 ] = 25 print (person)fruits_list = ['apple' , 'banana' , 'orange' ] fruits_tuple = tuple (fruits_list) print (fruits_tuple)
这里有一个非常值得探讨的问题,我们已经有了列表这种数据结构,为什么还需要元组这样的类型呢?
元组中的元素是无法修改的,事实上我们在项目中尤其是多线程 环境(后面会讲到)中可能更喜欢使用的是那些不变对象
一方面因为对象状态不能修改,所以可以避免由此引起的不必要的程序错误,简单的说就是一个不变的对象要比可变的对象更加容易维护;
另一方面因为没有任何一个线程能够修改不变对象的内部状态,一个不变对象自动就是线程安全的,这样就可以省掉处理同步化的开销。一个不变对象可以方便的被共享访问;
所以结论就是:如果不需要对元素进行添加、删除、修改的时候,可以考虑使用元组,当然如果一个方法要返回多个值,使用元组也是不错的选择。
元组在创建时间和占用的空间上面都优于列表。可以使用sys
模块的getsizeof
函数来检查存储同样的元素的元组和列表各自占用了多少内存空间,这个很容易做到。我们也可以在ipython
中使用魔法指令%timeit
来分析创建同样内容的元组和列表所花费的时间
3.6 集合 Python中的集合跟数学上的集合是一致的,不允许有重复元素,而且可以进行交集、并集、差集等运算。
可以按照下面代码所示的方式来创建和使用集合。
1 2 3 4 5 6 7 8 9 10 11 set1 = {1 , 2 , 3 , 3 , 3 , 2 } print (set1)print ('Length =' , len (set1))set2 = set (range (1 , 10 )) set3 = set ((1 , 2 , 3 , 3 , 2 , 1 )) print (set2, set3)set4 = {num for num in range (1 , 100 ) if num % 3 == 0 or num % 5 == 0 } print (set4)
向集合添加元素和从集合删除元素。
1 2 3 4 5 6 7 8 9 set1.add(4 ) set1.add(5 ) set2.update([11 , 12 ]) set2.discard(5 ) if 4 in set2: set2.remove(4 ) print (set1, set2)print (set3.pop())print (set3)
集合的成员、交集、并集、差集等运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 print (set1 & set2)print (set1 | set2)print (set1 - set2)print (set1 ^ set2)print (set2 <= set1)print (set3 <= set1)print (set1 >= set2)print (set1 >= set3)
说明: Python中允许通过一些特殊的方法来为某种类型或数据结构自定义运算符,上面的代码中我们对集合进行运算的时候可以调用集合对象的方法,也可以直接使用对应的运算符,例如&
运算符跟intersection方法的作用就是一样的,但是使用运算符让代码更加直观。
3.7 字典 字典是另一种可变容器模型,Python中的字典跟我们生活中使用的字典是一样一样的,它可以存储任意类型对象,与列表、集合不同的是,字典的每个元素都是由一个键和一个值组成的“键值对”,键和值通过冒号分开。下面的代码演示了如何定义和使用字典。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 scores = {'弘树' : 95 , '白元芳' : 78 , '狄仁杰' : 82 } print (scores)items1 = dict (one=1 , two=2 , three=3 , four=4 ) items2 = dict (zip (['a' , 'b' , 'c' ], '123' )) items3 = {num: num ** 2 for num in range (1 , 10 )} print (items1, items2, items3)print (scores['骆昊' ])print (scores['狄仁杰' ])for key in scores: print (f'{key} : {scores[key]} ' ) scores['白元芳' ] = 65 scores['诸葛王朗' ] = 71 scores.update(冷面=67 , 方启鹤=85 ) print (scores)if '武则天' in scores: print (scores['武则天' ]) print (scores.get('武则天' ))print (scores.get('武则天' , 60 ))print (scores.popitem())print (scores.popitem())print (scores.pop('骆昊' , 100 ))scores.clear() print (scores)