Python最基本的内置数据类型包括:
- 布尔型(表示真假的类型,仅包含True和False两种取值);
- 整型(整数,例如42、10000000);
- 浮点型(小数,例如3.14159,或用科学计数法表示的数字,例如1.0e8,它表示1乘以10的8次方,也可写作10000000.0);
- 字符串型(字符组成的序列);
一、变量
Python里所有数据——布尔值、整数、浮点数、字符串,甚至大型数据结构、函数以及程序都是以对象(object)的形式存在的。这使得Python语言具有很强的统一性(还有许多其他有用的特性),而这恰恰是许多其他语言所缺少的。
对象就像一个塑料盒子,里面装的是数据,对象有不同类型,例如布尔型和整型,类型决定了可以对它进行的操作。现实生活中的"陶器"会暗含一些信息(例如它可能很重,注意不要掉到地上,等等)。
类似地,Python中一个类型为int的对象会告诉你:可以把它与另一个int对象相加。
对象的类型还决定了它装着的数据是允许被修改的变量(可变的)还是不可被修改的常量(不可变的)。你可以把不可变对象想象成一个透明但封闭的盒子:你可以看到里面装的数据,但是无法改变它。类似地,可变对象就像一个开着口的盒子,你不仅可以看到里面的数据,还可以拿出来修改它,但你无法改变这个盒子本身,即你无法改变对象的类型。
Python是强类型的(strongly typed),你永远无法修改一个已有对象的类型,即使它包含的值是可变的。
编程语言允许你定义变量(variable),所谓变量就是在程序中为了方便地引用内存中的值而为它取的名称。在Python中,我们用 = 来给一个变量赋值。
下面这段仅两行的Python程序首先将整数7赋值给了变量a,之后又将a的值打印了出来:
>>> a = 7
>>> print(a)
7
注意,Python中的变量有一个非常重要的性质:它仅仅是一个名字。赋值操作并不会实际复制值,它只是为数据对象取个相关的名字。
名字是对对象的引用而不是对象本身,你可以把名字想象成贴在盒子上的标签。
试着在交互式解释器中执行下面的操作:
- 和之前一样,将7赋值给名称a,这样就成功创建了一个包含整数7的对象;
- 打印a的值;
- 将a赋值给b,这相当于给刚刚创建的对象又贴上了标签b;
- 打印b的值;
>>> a = 7
>>> print(a)
7
>>> b = a
>>> print(b)
7
在Python中,如果想知道一个对象(例如一个变量或者一个字面值)的类型,可以使用语句:type( thing )。
试试对不同的字面值(58、99.9、abc)以及不同的变量(a、b)执行type操作:
>>> type(a)
<class 'int'>
>>> type(b)
<class 'int'>
>>> type(58)
<class 'int'>
>>> type(99.9)
<class 'float'>
>>> type('abc')
<class str'>
变量名只能包含以下字符:
- 小写字母(a~z);
- 大写字母(A~Z);
- 数字(0~9);
- 下划线(_);
名字不允许以数字开头。此外,Python中以下划线开头的名字有特殊的含义。
下面是一些合法的名字:
a
a1
a_b_c_95
_abb_
_1a
下面这些名字则是非法的:
1
1a
1_
最后要注意的是,不要使用下面这些词作为变量名,它们是Python保留的关键字:
二、数字
Python本身支持整数(比如5和100000000)以及浮点数(比如3.1416、14.99和1.87e4)。
你可以对这些数字进行下表中的计算:
1、整数
任何仅含数字的序列在Python中都被认为是整数:
>>> 5
5
你可以单独使用数字零(o)
>>> 0
0
但不能把它作为前缀放在其他数字前面:
>>> 05
File "<stdin>", line 1
05
^
SyntaxError:invalid token
一个数字序列定义了一个正整数。你也可以显式地在前面加上正号+,这不会使数字发生任何改变:
>>> 123
123
>>> +123
123
在数字前添加负号-可以定义一个负数:
>>>-123
-123
你可以像使用计算器一样使用Python来进行常规运算。Python支持的运算参见之前的表格。试试进行加法和减法运算,运算结果和你预期的一样:
>>> 5 + 9
14
>>> 100 - 7
93
>>> 4 - 10
-6
可以连续运算任意个数:
>>> 5 + 9 + 3
17
>>> 4 + 3 - 2 - 1 + 6
10
格式提示:数字和运算符之间的空格不是强制的,你也可以写成下面这种格式:
>>> 5 + 9 + 3
17
只不过添加空格会使代码看起来更规整更便于阅读。
乘法运算的实现也很直接:
>>> 6 * 7
42
>>> 7 * 6
42
>>> 6 * 7 * 2 * 3
252
除法运算比较有意思,可能与你预期的有些出入,因为Python里有两种除法:
- / 用来执行浮点除法(十进制小数);
- // 用来执行整数除法(整除);
与其他语言不同,在Python中即使运算对象是两个整数,使用/仍会得到浮点型的结果:
>>> 9 / 5
1.8
使用整除运算得到的是一个整数,余数会被截去:
>>>> 9 // 5
1
之前的例子中我们都在使用立即数进行运算,你也可以在运算中将立即数和已赋值过的变量混合使用:
>>> a = 95
>>> a
95
>>> a - 3
92
上面代码中出现了a-3,但我们并没有将结果赋值给a,因此a的值并未发生改变:
>>> a
95
如果你想要改变a的值,可以这样写:
>>> a = a - 3
>>> a
92
对于初学者来说,上面这行式子可能很费解,因为小学的数学知识让我们根深蒂固地认为=代表等于,因此上面的式子显然是不成立的。但在Python里并非如此,Python解释器会首先计算=右侧的表达式,然后将其结果赋值给左侧的变量。
试着这样理解看看是否有帮助。
- 计算a-3;
- 将运算结果保存在一个临时变量中;
- 将这个临时变量的值赋值给a;
>>> a = 95
>>> temp = a - 3
>>> a = temp
因此,当输入:
>>> a = a - 3
Python 实际上先计算了右侧的减法,暂时记住运算结果,然后将这个结果赋值给了=左侧的a。这种写法比使用临时变量要更加迅速、简洁。
你还可以进一步将运算过程与赋值过程进行合并,只需将运算符放到=前面。
例如,a -= 3 等价于a = a - 3:
>>> a = 95
>>> a -= 3
>>> a
92
下面的代码等价于执行a = a + 8:
>>> a += 8
>>> a
100
以此类推,下面的代码等价于a = a * 2:
>>> a *= 2
>>> a
200
再试试浮点型除法,例如 a = a / 3:
>>> a /= 3
>>> a
66.666666666667
接着将13赋值给a,然后试试执行a=a//4(整数除法)的简化版:
>>> a = 13
>>> a //= 4
>>> a
3
百分号%在Python里有多种用途,当它位于两个数字之间时代表求模运算,得到的结果是第一个数除以第二个数的余数:
>>> 9 % 5
4
使用下面的方法可以同时得到余数和商:
>>> divmod(9,5)
(1,4)
或者你也可以分别计算:
>>> 9 // 5
1
>>> 9 % 5
4
上面的代码出现了一些你没见过的新东西:一个叫作divmod的函数。这个函数接受了两个整数:9和5,并返回了一个包含两个元素的结果,我们称这种结构为元组(tuple)。
2、优先级
想一想下面的表达式会产生什么结果?
>>> 2 + 3 * 4
如果你先进行加法运算2+3=5,然后计算5*4,最终得到20。但如果你先进行乘法运算,3*4=12,接着2+12,结果等于14。
与其他编程语言一样,在Python里,乘法的优先级要高于加法,因此第二种运算结果是正确的:
>>> 2 + 3 * 4
14
如何了解优先级规则?我在附录F中为你准备了一张优先级表,但在实际编程中我几乎从来没有查看过它,因为我们总可以使用括号来保证运算顺序与我们期望的一致:
>>> 2 + (3 * 4)
14
这样书写的代码也可让阅读者无需猜测代码的意图,免去了检查优先级表的麻烦。
3、基数
在Python中,整数默认使用十进制数(以10为底),除非你在数字前添加前缀,显式地指定使用其他基数(base)。也许你永远都不会在自己的代码中用到其他基数,但你很有可能在其他人编写的Python代码里见到它们。
我们大多数人都有10根手指10根脚趾(我家里倒是有只猫多了几根指头,但我从来没见过它用自己的指头数数)。因此,我们习惯这样计数:0,1,2,3,4,5,6,7,8,9。到了9之后,我们用光了所有的数字,于是将数字1放到“十位”,并把0放到“个位”。因此,10代表"1个十加0个一"。我们无法用一个字符代表数字"十"。接着是11,12,一直到19,然后仿照之前的做法,我们将新多出来的1加到十位来组成20(2个十加0个一),以此类推。
基数指的是在必须进位前可以使用的数字的最大数量。以2为底(二进制)时,可以使用的数字只有0和1。这里的0和十进制的0代表的意义相同,1和十进制的1所代表的意义也相同。然而以2为底时,1与1相加得到的将是10(1个二加0个一)。
在Python中,除十进制外你还可以使用其他三种进制的数字:
- 0b或0B代表二进制(以2为底);
- 0o或00代表八进制(以8为底);
- 0×或0X代表十六进制(以16为底);
Python解释器会打印出它们对应的十进制整数。我们来试这些不同进制的数。首先是单纯的十进制数字10,代表"1个十加0个一"。
>>> 10
10
接着,试试二进制(以2为底),代表“1(十进制)个二加上0个一:
>>> 0b10
2
八进制(以8为底),代表“1(十进制)个八加上0个一":
>>> 0o10
8
十六进制(以16为底),代表“1(十进制)个16加上0个一”:
>>> 0x10
16
可能你会好奇,十六进制用的是哪16个"数字",它们是:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e以及f。
因此,oxa代表十进制的10,oxf代表十进制的15,0xf加1等于 θx10(十进制16)。
为什么要使用10以外的基数?因为它们在进行位运算时非常有用。
4、类型转换
我们可以方便地使用int()函数将其他的Python数据类型转换为整型。它会保留传入数据的整数部分并舍去小数部分。
Python里最简单的数据类型是布尔型,它只有两个可选值:True和False。当转换为整数时,它们分别代表1和0:
>>> int(True)
1
>>> int(False)
0
当将浮点数转换为整数时,所有小数点后面的部分会被舍去:
>>> int(98.6)
98
>>> int(1.0e4)
10000
也可以将仅包含数字和正负号的字符串(如果你不知道字符串是什么,不用着急,先往后读,很快就会了解)转换为整数,下面有几个例子:
>>> int('99')
99
>>> int('-23')
-23
>>> int('+12')
12
将一个整数转换为整数没有太多意义,这既不会产生任何改变也不会造成任何损失:
>>> int(12345)
12345
如果混合使用多种不同的数字类型进行计算,Python会自动地进行类型转换:
>>> 4 + 7.0
11.8
与整数或浮点数混合使用时,布尔型的False会被当作θ或0.6,Ture会被当作1或1.0:
>>> True + 2
3
>>> False +5.0
5.0
5、浮点数
整数全部由数字组成,而浮点数(在Python里称为float)包含非数字的小数点。
浮点数与整数很像:你可以使用运算符(+、-、*、//、**和%)以及divmod()函数进行计算。
使用float()函数可以将其他数字类型转换为浮点型。与之前一样,布尔型在计算中等价于1.0和0.0:
>>> float(True)
1.0
>>> float(False)
0.0
将整数转换为浮点数仅仅需要添加一个小数点:
>>> float(98)
98.0
>>> float('99')
99.0
此外,也可以将包含有效浮点数(数字、正负号、小数点、指数及指数的前缀e)的字符串转换为真正的浮点型数字:
>>> float('98.6')
98.6
>>> float('-1.5')
-1.5
>>> float('1.0e4')
10000.0
三、字符串
对Unicode的支持使得Python3可以包含世界上任何书面语言以及许多特殊符号。对于Unicode 的支持是Python3从Python2分离出来的重要原因之一,也正是这一重要特性促使人们转向使用Python3。
字符串型是我们学习的第一个Python序列类型,它的本质是字符序列。
与其他语言不同的是,Python字符串是不可变的。你无法对原字符串进行修改,但可以将字符串的一部分复制到新字符串,来达到相同的修改效果。很快你就会学到如何实现。
1、使用引号创建
将一系列字符包裹在一对单引号或一对双引号中即可创建字符串,就像下面这样:
>>>> 'Snap'
'Snap'
>>> "Crackle"
'Crackle'
交互式解释器输出的字符串永远是用单引号包裹的,但无论使用哪种引号,Python对字符串的处理方式都是一样的,没有任何区别。
既然如此,为什么要使用两种引号?这么做的好处是可以创建本身就包含引号的字符串,而不用使用转义符。可以在双引号包裹的字符串中使用单引号,或者在单引号包裹的字符串中使用双引号。
你还可以使用连续三个单引号''',或者三个双引号"""创建字符串:
>>> ''Boom!'''
'Boom'
>>> """Eek!"""
'Eek!'
三元引号在创建短字符串时没有什么特殊用处,它多用于创建多行字符串。
如果你尝试通过单独的单双引号创建多行字符串,在你完成第一行并按下回车时,Python 会弹出错误提示:
>>> poem = 'There was a young lady of Norway,
File "<stdin>", line 1
poem = 'There was a young lady of Norway,
^
SyntaxError: EOL while scanning string literal
>>>
在三元引号包裹的字符串中,每行的换行符以及行首或行末的空格都会被保留:
>>>> poem2= '''I do not like thee,Doctor Fell.
... The reason why, I cannot tell.
... But this I know, and know full well:
... I do not like thee,Doctor Fell.
... '''
>>> print(poem2)
I do not like thee,Doctor Fell.
The reason why,I cannot tell.
But this I know, and know full well:
I do not like thee,Doctor Fell.
>>>
值得注意的是,print()函数的输出与交互式解释器的自动响应输出存在一些差异。
print()会把包裹字符串的引号截去,仅输出其实际内容,易于阅读。
它还会自动地在各个输出部分之间添加空格,并在所有输出的最后添加换行符,解释器可以打印字符串以及像\n的转义符。
最后要指出的是Python允许空串的存在,它不包含任何字符且完全合法。
2、使用str()进行类型转换
使用str()可以将其他Python数据类型转换为字符串:
>>> str(98.6)
'98.6'
>>> str(1.0e4)
'10000.0'
>>> str(True)
'True'
当你调用 print()函数或者进行字符串差值(string interpolation)时,Python 内部会自动使用str()将非字符串对象转换为字符串。
3、使用 [start:end:step] 分片
分片操作(slice)可以从一个字符串中抽取子字符串(字符串的一部分)。我们使用一对方括号、起始偏移量start、终止偏移量end以及可选的步长step来定义一个分片。其中一些可以省略。分片得到的子串包含从start开始到end之前的全部字符。
- [:] 提取从开头到结尾的整个字符串;
- [start:] 从start提取到结尾;
- [:end] 从开头提取到end-1;
- [start:end] 从start提取到end-1;
- [start:end:step] 从start提取到end-1,每step个字符提取一个;
与之前一样,偏移量从左至右从0、1开始,依次增加;从右至左从-1、-2开始,依次减小。如果省略start,分片会默认使用偏移量0(开头);如果省略 end,分片会默认使用偏移量-1(结尾)。
我们来创建一个由小写字母组成的字符串:
>>> Letters = 'abcdefghijklmnopqrstuvwxyz'
仅仅使用:分片等价于使用θ:-1(也就是提取整个字符串):
>>> letters[:]
'abcdefghijklmnopqrstuvwxyz'
下面是一个从偏移量20提取到字符串结尾的例子:
>>> letters[20:]
'uwwxyz'
现在,从偏移量10提取到结尾:
>>> letters[10:]
'klmnopqrstuwwxyz'
下一个例子提取了偏移量从12到14的字符(Python的提取操作不包含最后一个偏移量对应的字符):
>>> Letters[12:15]
'mno'
提取最后三个字符:
>>> letters[-3:]
'xyz'
下面一个例子提取了从偏移量为18的字符到倒数第4个字符。注意与上一个例子的区别:当偏移量-3作为开始位置时,将获得字符×;而当它作为终止位置时,分片实际上会在偏移量-4处停止,也就是提取到字符w:
>>> letters[18:-3]
'stuw'
接下来,试着提取从倒数第6个字符到倒数第3个字符:
>>> letters[-6:-2]
'uvwx'
如果你需要的步长不是默认的1,可以在第二个冒号后面进行指定,就像下面几个例子所示。
从开头提取到结尾,步长设为7:
>>> letters[::7]
'ahov'
从偏移量4提取到偏移量19,步长设为3:
>>> letters[4:20:3]
'ehknqt'
从偏移量19提取到结尾,步长设为4:
>>> letters[19::4]
'tx'
从开头提取到偏移量20,步长设为5:
>>> letters[:21:5]
'afkpu'
记住,分片中end的偏移量需要比实际提取的最后一个字符的偏移量多1。
是不是非常方便?但这还没有完。如果指定的步长为负数,机智的Python还会从右到左反向进行提取操作。下面这个例子便从右到左以步长为1进行提取:
>>> letters[-1::-1]
'zyxwvutsrqponmlkjihgfedcba'
事实上,你可以将上面的例子简化为下面这种形式,结果完全一致:
>>> letters[::-1]
'zyxwvutsrqponmlkjihgfedcba'
分片操作对于无效偏移量的容忍程度要远大于单字符提取操作。在分片中,小于起始位置的偏移量会被当作θ,大于终止位置的偏移量会被当作-1,就像接下来几个例子展示的一样。
提取倒数50个字符:
>>> letters[-50:]
'abcdefghijklmnopqrstuwwxyz'
提取从倒数第51到倒数第50个字符:
>>> letters[-51:-50]
''
从开头提取到偏移量为69的字符:
>>> letters[:70]
'abcdefghijklmnopqrstuwwxyz'
从偏移量为70的字符提取到偏移量为71的字符:
>>> letters[70:71]
''
4、使用len()获得长度
到目前为止,我们已经学会了使用许多特殊的标点符号(例如+)对字符串进行相应操作。但标点符号只有有限的几种。从现在开始,我们将学习使用Python的内置函数。所谓函数指的是可以执行某些特定操作的有名字的代码。
len()函数可用于计算字符串包含的字符数:
>>> len(letters)
26
>>> empty = ""
>>> len(empty)
0
也可以对其他的序列类型使用len()。
5、使用split()分割
与广义函数len()不同,有些函数只适用于字符串类型。为了调用字符串函数,你需要输入字符串的名称、一个点号,接着是需要调用的函数名,以及需要传入的参数:string. function(arguments)。
使用内置的字符串函数splft()可以基于分隔符将字符串分割成由若干子串组成的列表。所谓列表(list)是由一系列值组成的序列,值与值之间由逗号隔开,整个列表被方括号所包裹。
>>>> todos = 'get gloves,get mask,give cat vitamins,call ambulance'
>>> todos.split(',')
['get gloves', 'get mask', 'give cat vitamins', 'call ambulance']
上面例子中,字符串名为todos,函数名为split(),传入的参数为单一的分隔符','。如果不指定分隔符,那么split() 将默认使用空白字符-------换行符、空格、制表符。
>>> todos.split()
['get', 'gloves,get', 'mask,give', 'cat', 'vitamins,call', 'ambulance']
即使不传入参数,调用split()函数时仍需要带着括号,这样Python才能知道你想要进行函数调用。
6、使用join()合并
可能你已经猜到了,join()函数与split()函数正好相反:它将包含若干子串的列表分解,并将这些子串合成一个完整的大的字符串。join()的调用顺序看起来有点别扭,与split()相反,你需要首先指定粘合用的字符串,然后再指定需要合并的列表:string. join(List)。因此,为了将列表lines中的多个子串合并成完整的字符串,我们应该使用语句:'\n'.join(lines)。下面的例子将列表中的名字通过逗号及空格粘合在一起:
>>> crypto_list=['Yeti','Bigfoot','Loch Ness Monster']
>>> crypto_string =', '.join(crypto_list)
>>>> print('Found and signing book deals:',crypto_string)
Found and signing book deals: Yeti, Bigfoot, Loch Ness Monster
7、使用replace()替换
使用replace()函数可以进行简单的子串替换。你需要传入的参数包括:需要被替换的子串,用于替换的新子串,以及需要替换多少处。最后一个参数如果省略则默认只替换第一次出现的位置:
>>> setup.replace('duck','marmoset')
'a marmoset goes into a bar...'
修改最多100处:
>>> setup.replace('a ','a famous ',100)
'a famous duck goes into a famous bar...'
当你准确地知道想要替换的子串是什么样子时,replace()是个非常不错的选择。但使用时一定要小心!
在上面第二个例子中,如果我们粗心地把需要替换的子串写成了单个字符的'a'而不是两个字符的'a '(a后面跟着一个空格)的话,会错误地将所有单词中出现的a也一并替换了:
>>> setup.replace('a','a famous',100)
'a famous duck goes into a famous ba famousr...'
有时,你可能想确保被替换的子串是一个完整的词,或者某一个词的开头等等,在这种情况下,你需要借助正则表达式。
四、列表
1、初识 list
list 是 Python 内置的一种高级数据类型。list 是一种有序的集合,在 python 中应用很广泛。
names = ['James', 'Michael', 'Emma', 'Emily']
print("names 的 数 据 类 型 : ",type(names))
print(names)
输出结果:
names 的 数 据 类 型 : <class 'list'>
['James', 'Michael', 'Emma', 'Emily']
用 len() 可获得 list 的长度,即 list 集合所包含的元素个数,如下:
n = len(names)
print(n)
输出结果:
4
如果 list 中一个元素也没有,我们可以定义一个空的 list ,则其长度为 0 ,如下:
empty_list = []
empty_list
输出结果:
[]
len(empty_list)
输出结果:
0
2、访问列表中的值
用索引来访问 list 中的每个元素,请注意索引是从 0 开始,最后一个的索引编号为 n-1,即所有元素的编号依次为(0,1, 2, …, n-1)。
list 中单个元素的访问如下:
names[0]
输出结果:
'James'
names[1]
输出结果:
'Michael'
如果要获取最后一个元素,也可以用 -1 来做索引,倒数第二个元素可以用 -2 来索引,其他以此类推。
names[-1]
输出结果:
'Emily'
names[-2]
输出结果:
'Emma'
可以通过 for 循环来列出所有元素。有两种方法可以实现,如下:
方法 1:
for name in names:
print(name)
输出结果:
James
Michael
Emma
Emily
方法 2:
for i in range(len(names)):
print(names[i])
输出结果:
James
Michael
Emma
Emily
3、列表的操作、函数及方法
1. list 中元素的增、改、删等操作
list 是一个可变的有序列表,可以通过添加、修改、删除等操作来操作 list 中的元素。
1)往 list 中添加元素
可以通过 append() 和 insert() 方法来往 list 中添加元素。
其中,append() 方法是在 list 的末尾添加元素;insert() 是在指定位置添加元素。
如下:
names.append('Jacob')
names
输出结果:
['James', 'Michael', 'Emma', 'Emily', 'Jacob']
names.insert(1, 'Ava')
names
输出结果:
['James', 'Ava', 'Michael', 'Emma', 'Emily', 'Jacob']
请注意,上述 insert() 方法中,“1” 表示在第 2 个位置添加新的元素(索引是从 0 开始的)。
2)删除 list 中的元素
用 pop() 方法删除 list 末尾的元素:
names.pop()
输出结果:
'Jacob'
names
输出结果:
['James', 'Ava', 'Michael', 'Emma', 'Emily']
删除指定位置的元素,用 pop(i) 方法:
names.pop(0)
输出结果:
'James'
names
输出结果:
['Ava', 'Michael', 'Emma', 'Emily']
3)修改 list 中的元素
如果需要修改 list 中的元素,可以直接通过 list 的索引进行赋值来实现,如下:
names[2] = 'Lemon'
names
输出结果:
['Ava', 'Michael', 'Lemon', 'Emily']
2. 列表操作符
列表可以进行相加 “+” 和相乘 “*” 运算,“+” 相当于拼接列表,“*” 相当于重复列表。
此外,还可以判断元素是否存在于列表中。
# 列表相加
print(" 列表相加 : ",[1,2,3]+['a','b'])
# 列表相乘
print(" 列表相乘 : ",['a','b']*3)
# 判断元素是否存在于列表中
print(" 判断元素是否存在于列表中: ", 'a' in ['a', 'b'])
print(" 判断元素是否存在于列表中: ", 'a' not in ['a', 'b'])
输出结果:
- 列表相加: [1, 2, 3, 'a', 'b']
- 列表相乘: ['a', 'b', 'a', 'b', 'a', 'b']
- 判断元素是否存在于列表中: True
- 判断元素是否存在于列表中: False
3. 列表函数 & 方法
列表的函数包括:
- len(list):列表元素个数,即列表的长度;
- max(list):返回列表元素最大值;
- min(list):返回列表元素最小值;
- list(sep):将元组转为列表;
列表的方法除了前面提到的增、改、删等方法外,还有其他一些方法,如下:
- list.count(obj):统计某个元素在列表中出现的次数;
- list.extend(seq):在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
- list.index(obj):从列表中找出某个值第一个匹配项的索引位置;
- list.remove(obj):移除列表中某个值的第一个匹配项;
- list.sort():对原列表进行排序;
- list.reverse():对原列表进行反向排序;
list1 = [1,2,3,9,6,3]
list2 = [3, 8, 5, 4, 7,4]
tuple1 = (3,9,6)
# 列 表 的 函 数
print(" 列 表 最 大 值 : ",max(list1))
print(" 列 表 最 小 值 : ",min(list1))
print(" 将 元 组 转 为 列 表 : ",list(tuple1))
# 列 表 的 方 法
print("count : ",list1.count(3))
list1.extend(list2)
print("extend : ",list1)
print("index : ",list2.index(4))
list2.remove(4)
print("remove : ",list2)
list2.sort()
print("sort : ",list2)
list2.reverse()
print("reverse : ",list2)
输出结果:
- 列表最大值 : 9
- 列表最小值 : 1
- 将元组转为列表 : [3, 9, 6]
- count : 2
- extend : [1, 2, 3, 9, 6, 3, 3, 8, 5, 4, 7, 4]
- index : 3
- remove : [3, 8, 5, 7, 4]
- sort : [3, 4, 5, 7, 8]
- reverse : [8, 7, 5, 4, 3]
4、list 中元素的类型可以多样
同一个 list 中的元素的类型可以是字符串(str)、整型(int)、布尔型(Boolean)、以及嵌套的 list 等,举例如下:
a_list = ['Lemon', 100, ['a', 'b', 'c', 'd'], True]
a_list
输出结果:
['Lemon', 100, ['a', 'b', 'c', 'd'], True]
a_list[0]
输出结果:
'Lemon'
a_list[2]
输出结果:
['a', 'b', 'c', 'd']
在上述的 a_list 中,第 3 个元素 (即 alist[2]) 其实本身也是一个 list。
list 中的元素也可以是 list,这样的话,可以进行多重 list 的嵌套。
上述 list,也可以按下述方式来理解。
b_list = ['a', 'b', 'c', 'd']
a_list = ['Lemon', 100, b_list, True]
a_list
输出结果:
['Lemon', 100, ['a', 'b', 'c', 'd'], True]
针对 a_list ,如果想获取其中元素 b_list 里面的单个元素 “b”,该如何实现呢?
其实,这个类似二维数组,用二维的索引可以获取,如下:
item_b = a_list[2][1]
item_b
输出结果:
'b'
上述 [2] 表示获取 a_list 的第 3 个元素,即 b_list,[1] 表示获取 b_list 的第 2 个元素,即“b”。
5、list 的切片(slices)
前面描述了 list 中单个元素如何获取,如果想获取其中连续的部分元素,该如何实现呢。
这里可以通过切片 (slices) 的形式来获取部分连续的元素。
c_list = ['James', 'Ava', 'Michael', 'Emma', 'Emily', 'Jacob']
c_list
输出结果:
['James', 'Ava', 'Michael', 'Emma', 'Emily', 'Jacob']
list 中以切片形式使用时,其结构可参考 new_list[start: end : step]
其中 “start” 和 “end” 表示索引位置的开始和结束,选取的元素包含 “start”,但不包含 “end”。
“step” 表示步长,默认情况下,“step”为 1,演示如下:
Example-1:
c_list[1:3]
输出结果:
['Ava', 'Michael']
example-1 中,1:3 表示切片选取的是第 2 个元素和第 3 个元素,即包含索引为 1 和索引为 2 的元素,相当于获取 c_list[1] 和 c_list[2]。
Example-2:
c_list[::2]
输出结果:
['James', 'Michael', 'Emily']
example-2 中 “start” 和 “end” 为空的时候,默认是全选,即 “start” 为 0,“end” 为 len(c_list)-1。
所以 c_list[::2] 表示的是从索引为 0 开始,以步长为 2 来选择元素。
接下来看以下结合上述两个例子的演示:
c_list[1:3:2]
输出结果:
['Ava']
Example-3:
前面提到,new_list[-1] 表示获取最后一个元素,在切片的步长 “step” 中,也可以是负数,比如 “-1”:
c_list[::-1]
输出结果:
['Jacob', 'Emily', 'Emma', 'Michael', 'Ava', 'James']
从上述结果可以看出,当 “step”为 -1 时,我们发现是将列表进行了逆序排序。
再看看步长为 “-2” 时的结果:
c_list[::-2]
输出结果:
['Jacob', 'Emma', 'Ava']
可以这么理解,当步长为正数时,是从左到右以该步长来获取列表中的元素,而当步长为负数时,是从右到左以该步长的绝对值来获取列表中的元素。
Example-4:
如果想获取离散的元素,比如想获得第 1、2、4 个元素,能不能通过离散的索引值来获取呢?
我们先来试验一下:
c_list[0, 1, 3]
out:
TypeError Traceback (most recent call last) in () —-> 1 c_list[0, 1, 3]
TypeError: list indices must be integers or slices, not tuple
从运行结果可以之道,直接取离散的索引号是不行的,它提示 list 的索引必须是整数或者 slices。
那么,我们有没有方法来获取这些离散的元素呢?
方法肯定是有的,其中一种方法就是使用列表推导式。
6、列表推导式 (List Comprehension)
1. 列表推导式的一般情况
列表推导式的一般语法结构:
new_list = [x for x in iterable]
其中的 iterable 表示可迭代的对象,包括字符串(str)、列表(list),元组(tuple)、字典(dict)、集合(set)以及生成器(generator)等。
先来看几个简单的例子:
str_list = [x.lower() for x in "Lemon"]
str_list
输出结果:
['l', 'e', 'm', 'o', 'n']
list_list = [x**2 for x in [1,2,3,4]]
list_list
输出结果:
[1, 4, 9, 16]
tuple_list = [x+2 for x in (1,2,3,4)]
tuple_list
输出结果:
[3, 4, 5, 6]
ge_list = [x for x in range(8)]
ge_list
输出结果:
[0, 1, 2, 3, 4, 5, 6, 7]
2. 两层 for 循环的列表推导式
列表推导式中,可以同时包含多个 for 循环,比如同时两个 for 循环,如下:
[x**2+y for x in range(5) for y in range(4,7)]
输出结果:
[4, 5, 6, 5, 6, 7, 8, 9, 10, 13, 14, 15, 20, 21, 22]
上述结果跟下面的写法结果是一致的:
two_for_list = []
for x in range(5):
for y in range(4,7):
two_for_list.append(x**2+y)
print(two_for_list)
输出结果:
[4, 5, 6, 5, 6, 7, 8, 9, 10, 13, 14, 15, 20, 21, 22]
列表推导式中,三层或者三层以上的 for 循环一般很少用到。
3. 使用两个变量来生成 list
列表推导式也可以使用两个或多个变量来生成 list,结合字典的使用,举例如下:
d = {'x': '1', 'y':'2', 'z':'4'}
d_list = [k+'='+v for k,v in d.items()]
d_list
输出结果:
['z=4', 'y=2', 'x=1']
4. 含 if 语句的列表推导式
列表推导式中还可以引入 if 条件语句,如下:
if_list = [x**2 for x in range(10) if x%2==0]
if_list
输出结果:
[0, 4, 16, 36, 64]
上述列表推导式,如果用普通的 for 循环来编写的话,内容如下:
if_list_1 = []
for x in range(10):
if x%2==0:
if_list_1.append(x**2)
print(if_list_1)
输出结果:
[0, 4, 16, 36, 64]
通过对比,可以看出列表推导式的方式更显得 Pythonic。
当然,如果仅仅是编写上更简洁,可能不一定能显现出列表推导式的优势,下面我们来对比下上述两种方式的运行效率。
%%timeit
if_list = [x**2 for x in range(10) if x%2==0]
if_list
输出结果:
100000 loops, best of 3: 6.06 µs per loop
%%timeit
def for_loop():
if_list_1 = []
for x in range(10):
if x%2==0:
if_list_1.append(x**2)
return if_list_1
for_loop()
输出结果:
100000 loops, best of 3: 6.76 µs per loop
从上面的运行结果进行对比,可以看出列表推导式的运行效率要高于普通的 for 循环编写方式。
因为,建议大家使用列表推导式,不仅写法更 Pythonic,且运行效率更高。
包含 if-else 语句的列表推导式:
[x**2 if x%2==0 else x+2 for x in range(10)]
输出结果:
[0, 3, 4, 5, 16, 7, 36, 9, 64, 11]
包含两个 if 语句的列表推导式:
[x**2 for x in range(10) if x%2==0 if x%3==0]
输出结果:
[0, 36]
如果想获取离散的元素,比如想获得第 1、2、4 个元素,能不能通过离散的索引值来获取呢?
前面已经实践过,直接通过离散的索引值来获取列表中的元素是不行的。
通过列表推导式的学习,我们可以换一种思路,来实现列表中离散的元素的获取,如下:
[c_list[i] for i in [0,1,3]]
输出结果:
['James', 'Ava', 'Emma']
列表(list)作为 python 最基础也是最重要的数据类型之一,在 python 数据分析以及其他用途中有着重要的作用,希望上述内容能对于熟悉 list 有所帮助。
五、元祖
与列表类似,元组也是由任意类型元素组成的序列。与列表不同的是,元组是不可变的,这意味着一旦元组被定义,将无法再进行增加、删除或修改元素等操作。因此,元组就像是一个常量列表。
1、使用()创建元组
下面的例子展示了创建元组的过程,它的语法与我们直观上预想的有一些差别。
可以用()创建一个空元组:
>>> empty_tuple=()
>>> empty_tuple
()
创建包含一个或多个元素的元组时,每一个元素后面都需要跟着一个逗号,即使只包含一个元素也不能省略:
>>> one_marx = 'Groucho'
>>> one_marx
('Groucho',)
如果创建的元组所包含的元素数量超过1,最后一个元素后面的逗号可以省略:
>>> marx_tuple = 'Groucho', 'Chico', 'Harpo'
>>> marx_tuple
('Groucho', 'Chico', 'Harpo')
Python的交互式解释器输出元组时会自动添加一对圆括号。你并不需要这么做——定义元组真正靠的是每个元素的后缀逗号————但如果你习惯添加一对括号也无可厚非。
可以用括号将所有元素包裹起来,这会使得程序更加清晰:
>>> marx_tuple = ('Groucho', 'Chico', 'Harpo')
>>> marx_tuple
('Groucho', 'Chico', 'Harpo')
可以一口气将元组赋值给多个变量:
>>>> marx_tuple = ('Groucho','Chico','Harpo')
>>> a, b, c= marx_tuple
>>> a
'Groucho'
>>> b
'Chico'
>>> c
'Harpo'
有时这个过程被称为元组解包。
可以利用元组在一条语句中对多个变量的值进行交换,而不需要借助临时变量:
>>> password = 'swordfish'
>>> icecream = 'tuttifrutti'
>>> password, icecream = icecream, password
>>>password
'tuttifrutti'
>>> icecream
'swordfish'
>>>
tuple()函数可以用其他类型的数据来创建元组:
>>> marx_list = ['Groucho', 'Chico', 'Harpo']
>>> tuple(marx_list)
('Groucho', 'Chico', 'Harpo')
2、元组与列表
在许多地方都可以用元组代替列表,但元组的方法函数与列表相比要少一些——元组没有append()、insert(),等等——因为一旦创建元组便无法修改。
既然列表更加灵活,那为什么不在所有地方都使用列表呢?
原因如下所示:
- 元组占用的空间较小;
- 你不会意外修改元组的值;
- 可以将元组用作字典的键;
- 命名元组可以作为对象的替代;
- 函数的参数是以元组形式传递的;
六、字典
字典(dictionary)与列表类似,但其中元素的顺序无关紧要,因为它们不是通过像 0 或 1 的偏移量访问的。取而代之,每个元素拥有与之对应的互不相同的键(key),需要通过键来访问元素。键通常是字符串,但它还可以是Python中其他任意的不可变类型:布尔型、整型、浮点型、元组、字符串,以及其他一些在后面的内容中会见到的类型。字典是可变的,因此你可以增加、删除或修改其中的键值对。
如果使用过只支持数组或列表的语言,那么你很快就会爱上Python里的字典类型。
1、使用创建字典
用大括号({})将一系列以逗号隔开的键值对(key:value)包裹起来即可进行字典的创建。最简单的字典是空字典,它不包含任何键值对:
>>> empty_dict = {}
>>> empty_dict
{}
在交互式解释器中输入字典名会打印出它所包含的所有键值对:
>>> bierce
{'misfortune': 'The kind of fortune that never misses',
'positive': "Mistaken at the top of one's voice",
'day': 'A period of twenty-four hours,mostly misspent'}
2、使用dict()转换为字典
可以用dict()将包含双值子序列的序列转换成字典。你可能会经常遇到这种子序列,例如"Strontium,90,Carbon,14"或者"Vikings,20,Packers,7",等等,每个子序列的第一个元素作为键,第二个元素作为值。
首先,这里有一个使用 Lol (a list of two-item list)创建字典的小例子:
>>> lol = [['a', 'b'], ['c', 'd'], ['e', 'f']]
>>> dict(lol)
{'c': 'd', 'a': 'b', 'e': 'f'}
记住,字典中元素的顺序是无关紧要的,实际存储顺序可能取决于你添加元素的顺序。
可以对任何包含双值子序列的序列使用dict(),下面是其他例子。
包含双值元组的列表:
>>> lot= [ ('a', 'b'), ('c', 'd'), ('e', 'f') ]
>>> dict(lot)
{'c': 'd', 'a': 'b', 'e': 'f'}
包含双值列表的元组:
>>> tol=( ['a','b'], ['c','d'], ['e','f'] )
>>> dict(tol)
{'c':'d', 'a':'b', 'e':'f'}
双字符的字符串组成的列表:
>>> los = [ 'ab', 'cd', 'ef' ]
>>> dict(los)
{'c': 'd', 'a': 'b', 'e': 'f'}
双字符的字符串组成的元组:
>>> tos = ( 'ab', 'cd', 'ef' )
>>> dict(tos)
{'c': 'd', 'a': 'b', 'e': 'f' }
3、Python 中字典合并的实现方法
Python 中有时候需要将字典进行合并,先来看看下面的运行结果:
x = {'a':1, 'b':2}
y = {'b':4, 'c':5}
z = x.update(y)
来看看 z 的返回结果:
print(z)
None
发现 z 返回的是 None 值,并不是我们想要的结果。
再来看一下此时 x 的返回结果,发现 x 已经是合并的结果。
x
{'a': 1, 'b': 4, 'c': 5}
那么有没有比较简单的实现方法呢。下面我们来探索一下:
Method1:适用于 Python3.5 及以上版本。
在 Python3.5 以上版本(含 3.5),可以通过下列方法实现:
z1 = {**x, **y}
z1
{'a': 1, 'b': 4, 'c': 5}
Method2:自定义函数。
如果在 Python2 或 Python3.4 以及低于 3.4 的版本,要实现两个 dict 的合并,该怎样做呢?
先定义一个函数,然后用自定义函数来运行:
def merge(x,y):
z = x.copy()
z.update(y)
return z
z2 = merge(x,y)
z2
{'a': 1, 'b': 4, 'c': 5}
4、多个 dict 进行合并
如果是多个 dictionary 需要进行合并呢?
同样可以通过自定义的形式来实现。
def merge_dicts(*dict_args):
result = {}
for item in dict_args:
result.update(item)
return result
x1 = {'a':1, 'b':2}
y1 = {'b':4, 'c':5}
x2 = {'d':8, 'e':10}
z3 = merge_dicts(x1,y1,x2)
z3
{'a': 1, 'b': 4, 'c': 5, 'd': 8, 'e': 10}
此方法在 Python2 和 Python3 下都是可以运行的。
七、集合
集合就像舍弃了值,仅剩下键的字典一样。键与键之间也不允许重复。如果你仅仅想知道某一个元素是否存在而不关心其他的,使用集合是个非常好的选择。如果需要为键附加其他信息的话,建议使用字典。
1、使用set()创建集合
你可以使用set()函数创建一个集合,或者用大括号将一系列以逗号隔开的值包裹起来,如下所示:
>>> empty_set = set()
>>> empty_set
set()
>>> even_numbers = {0, 2, 4, 6, 8}
>>> even_numbers
{0, 8, 2, 4, 6}
>>> odd_numbers = {1,3,5,7,9}
>>> odd_numbers
{9, 3, 1, 5, 7}
与字典的键一样,集合是无序的。
2、使用set()将其他类型转换为集合
你可以利用已有列表、字符串、元组或字典的内容来创建集合,其中重复的值会被丢弃。
首先来试着转换一个包含重复字母的字符串:
>>> set('letters')
{'l', 'e', 't', 'r', 's'}
注意,上面得到的集合中仅含有一个'e'和一个't',尽管字符串'Letters'里各自包含两个。
再试试用列表建立集合:
>>>> set(['Dasher', 'Dancer', 'Prancer', 'Mason-Dixon'])
{'Dancer', 'Dasher', 'Prancer', 'Mason-Dixon'}
再试试元组:
>>> set('Ummagumma', 'Echoes', 'Atom Heart Mother'))
{'Ummagumma', 'Atom Heart Mother', 'Echoes'}
当字典作为参数传入 set()函数时,只有键会被使用:
>>> set({'apple':'red','orange':'orange','cherry':'red'})
{'apple', 'cherry', 'orange'}
标签:Python,数据类型,元素,list,列表,详解,字符串,元组
From: https://blog.51cto.com/u_11837698/6236679