任何Python 物件都可以当串列(list) 的各个元素。
串列(list)跟字串(string)的中文名称中,都有个「串」字,对于初学者而言满容易搞混。
不过如果看英文名称的话,应该就会分得很明白了。list 有「清单」的意思,串列列出清单,而string 是「串」的意思,串出文字。
Python串列(list)以[ ] 中括号来表示,例如['a', 'b', 'c'] 就是一个简单的串列,它的项目包括三个字串'a', 'b', 'c',并以逗号隔开,位置(index) 分别是0、1、2。
关于位置(index) ,在《Python 观念》这篇文章「从0开始起算」段落中,针对位置的算法有做详细说明。这满重要的,写程式的过程中,你会常常用到。
快速阅读
Python串列的特性
串列特性包括:
- 可以储存多个资料
就像建立一个资料清单,可以放入很多资料,相同的资料可以重复出现。 - 属于序列结构
序列,指的是串列内的值有顺序性,所以可以使用各种有关顺序的方法(Method) 进行操作;结构,指的是资料结构(data structure)是电脑中储存、组织资料的方式。 - 值是可变的(mutable)
可以删除、增加、修改串列的值,可以更动串列内的各个项目。
怎么建立Python串列呢?
直接加上中括号建立串列
建立Python串列,最直观的方式就是直接以中括号包覆你要建立串列的内容。
下方的例子,我们将想将三个字串 'steak'
, 'apple'
,'soup'
建成一个名为dinner的串列,打出 ['steak', 'apple', 'soup']
后,将这个串列指派给你设定的变数名称dinner
,便建立一个名为 dinner
的串列了。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>dinner = ['steak', 'apple', 'soup'] </code></span></span></span>
使用 list() 建立串列
透由list() 函式,将字串转换成各别字元组成的串列。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>print(list('steak'))
['s', 't', 'e', 'a', 'k']</code></span></span></span>
也可以将tuple 转换为串列,下方的例子就将名为breakfast 的tuple 转换为串列。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>breakfast = ('sandwich', 'milk')
>>>print(list(breakfast))
['sandwich', 'milk']</code></span></span></span>
而如果list() 的括号内,什么都没有填入,则会生成一个空串列。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>print(list())
[]</code></span></span></span>
使用字串方法 split()建立串列
split() 这个字串方法(Method),可以将字串(string) 拆开回传串列(list)。
split() 有两个参数,如果第2个参数没有输入,就默认为-1,看到几个分隔的依据就切割出几个项目。
split(分隔的依据, 分成几个)
以下方命名为 date 的字串为例,以/ 为切割点,将字串分拆为三个项目。因为第二个参数没有输入,所以分割全部。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>date = '2020/11/25'
>>>print(date.split('/'))
['2020', '11', '25']</code></span></span></span>
当你只要将字串分拆为两个项目,可以在引数输入1,回传的串列就只会填到1 的位置,串列内便只在0、1 两个位置上有项目。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>date = '2020/11/25'
>>>print(date.split('/',1))
['2020', '11/25']</code></span></span></span>
小结
当你在编写程式码时,你可以用前述三种操作来建立Python串列:
- 使用中括号 [ ]
- 使用
list()
函式 - 使用字串方法
split()
假如你现在要建立一个1到9,这9个字的字串串列(串列内含的东西是字串),依照小结所列的建立串列操作,你可以这么做:
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>['1', '2', '3', '4', '5', '6', '7', '8', '9']
>>>list('123456789')
>>>'1 2 3 4 5 6 7 8 9'.split()</code></span></span></span>
你可以试试,返回的值都是一样的串列,你可以视情况使用对你来说比较有利、方便的操作来建立串列。
串列基本操作
使用len()函式取得串列的项目数
在len()函式的括号内放入要计算串列项目的串列名称,或者直接把串列放进去也可以。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>letters = ['a', 'b', 'c', 'd' ,'e' ,'f', 'g']
>>>print(len(letters))
7
>>>print(len(['a','b']))
2</code></span></span></span>
使用index()方法,找到项目的位置
因为是方法(Method),所以要将index() 放在串列名称之后来使用,串列与方法中间还要以一句点连接。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>print(red.index('blood'))
1</code></span></span></span>
使用in、 not in 运算子检查是否存在
使用in 来检测时,如果检测的项目存在,会回传True,不存在则回传False。
用not in来检测时以此类推,不存在回传True,存在时则回传False。
接下来的例子,就使用命名为red 的串列来说明。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
print('flower' in red)
True
>>>print('dog' in red)
False
>>>print('flower' not in red)
False
>>>print('dog' not in red)
True</code></span></span></span>
使用count()方法,计算项目出现的次数
运用count()方法可以很快速地帮你算出,指定的项目出现几次,如果串列中没有这个项目就会回传0。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'hair', 'hair']
>>>print(red.count('hair'))
3
>>>print(red.count('tomato'))
0</code></span></span></span>
串列的提取、改变、增减、排序操作
除了前述的基本操作,串列的操作主要可分为5 个面向,利用这样的分类,帮助你知道有那些工具可以运用于串列上。
- 把资料拿出来
- 改变资料内容
- 增加资料
- 删除资料
- 排序资料
接下来就依照这五个面向,分别介绍串列中提取、改变、增加、删除、排序的操作。
提取串列中的项目
Python串列像是经过排序的清单,有顺序性,所以可以依照各个项目存在的位置,提取所需要的资料。
[ ]填入位置,只能是整数,且不能超出串列内项目的数量。
提取单一个项目
在串列名称后方加上一个中括号,填入提取的资料所在位置。
举例来说,建立一个名为letters 的串列,并且依序印出在位置0、5、-1 的项目。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>letters = ['a', 'b', 'c', 'd' ,'e' ,'f', 'g']
>>>print(letters[0])
>>>print(letters[5])
>>>print(letters[-1])
a
f
g</code></span></span></span>
-1 位置指的是最后一个项目,只要你是针对最后一个项目,都可以用-1 来操作。当然空串列就无法找到 -1 位置的项目,只有空串列不适用。
如果使用浮点数(float) 或者提取的位置范围超过了,Python 都会回传错误给你。
当你填入浮点数,就是有小数点的数字,会出现TypeError。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>letters = ['a', 'b', 'c', 'd' ,'e' ,'f', 'g']
>>>print(letters[1.8])
print(letters[1.8])
TypeError: list indices must be integers or slices, not float</code></span></span></span>
而当位置超出范围时,会出现IndexError。下方的例子中,范围只能是-7 ~ 6,负数的部分,是从串列尾端代表-1 ,右至左-1 、-2…这样数过来。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>letters = ['a', 'b', 'c', 'd' ,'e' ,'f', 'g']
>>>print(letters[10])
print(letters[10])
IndexError: list index out of range</code></span></span></span>
提取子串列
使用slice 提取串列中的子串列,于提取单一项目一样,在串列名称后方加上中括号,并在括号内要提取的起点与终点,更讲究的时候,还可以要求固定间隔多少项目进行提取。
中括号以冒号区隔,分别填入
[起点: 终点: 间隔]
这个中括号内只有冒号不能省略,其他都可以省略。如果省略冒号,就等于是提取一个单一项目,而不是子串列。
口语一点就是,[2] 是拿index 在2的值;[2:] 则是从index 2的位置上切一刀,取一整段的值。
省略时,预设值为[0: 提取到最后一个:1]
值得注意的是,当你设定终点时,提取出来的项目会是起点位置到终点前一个项目,也就是你设定终点位置的项目不会提出来。
下方的例子中red 串列有6 个项目
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake', 'bird', 'cloud']</code></span></span></span>
位置分别为0、1、2、3、4、5,当你将终点设为5的时候,并不会提取最后一个项目'cloud',而只会提取项目到n-1。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake', 'bird', 'cloud']
>>>print((red[0:5:2]))
['flower', 'hair', 'bird']
>>>print((red[:5:2]))
['flower', 'hair', 'bird']
>>>print((red[:5:]))
['flower', 'blood', 'hair', 'cake', 'bird']
>>>print(red[::3])
['flower', 'cake']
>>>print(red[:])
['flower', 'blood', 'hair', 'cake', 'bird', 'cloud']</code></span></span></span>
除此之外,提取的子串列可以选择由右到左这个方向,只需在间隔值参数,填上负号 – 即可,下方例子我们填入-1,便由右边往左边提取子字串了。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake', 'bird', 'cloud']
>>>print((red[::-1]))
['cloud', 'bird', 'cake', 'hair', 'blood', 'flower']
</code></span></span></span>
使用slice 时可以指定无效的范围,不会造成例外,只会取得最接近的值。
多重指定 (multiple assignment)
利用串列,一次指定多个值给不同的变数,变数的数量需与串列中的项目数量一致。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>buy, donate, dye = red
>>>print(buy, donate, dye)
flower blood hair</code></span></span></span>
当然也可以一个一个慢慢指定,得到的结果是一样的。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>gift = red[0]
>>>afraid = red[1]
>>>prefer = red[2]
>>>print(gift, afraid, prefer)
flower blood hair</code></span></span></span>
改变串列内的项目
运用提取项目的操作,将希望改变的项目指派给串列
下方的例子中,将 red 这个串列,位置1 的字串,把原本的'blood ' 改为'dog',印出来的串列确实在位置1 上出现'dog' 字串。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake']
>>>red[1] = 'dog'
>>>print(red)
['flower', 'dog', 'hair', 'cake']</code></span></span></span>
除了可以一次改变一个项目外,也可以运用slice,同时改变多个项目。
下面的例子中,要求在位置1 到3 个项目中,以2 为间隔值由左向右的替换项目为'dog' 与'tomato'。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake', 'bird', 'cloud']
>>>red[1:4:2] = ['dog', 'tomato']
>>>print(red)
['flower', 'dog', 'hair', 'tomato', 'bird', 'cloud']</code></span></span></span>
增加串列的项目
使用* 运算子,重复多个串列
在串列至后加上* 及要重复的次数。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>print(['Yes! '] * 3)
['Yes! ', 'Yes! ', 'Yes! ']</code></span></span></span>
使用+ 运算子,将串列相加
在串列之后输入+ ,及要增加的串列。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>print(['Yes! '] * 3 + ['very good!'])
['Yes! ', 'Yes! ', 'Yes! ', 'very good!']</code></span></span></span>
使用extend() 方法,将串列相加
extend 的英文意思是扩展、增加长度,使用这个方法时,我们将顺序放在前的的串列作为扩充的主体,在该串列上使用extend(),要被增加上去的串列放在括号内。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake', 'bird', 'cloud']
>>>add_red = ['dog','tomato']
>>>red.extend(add_red)
>>>print(red)</code></span></span></span>
输出的结果
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>['flower', 'blood', 'hair', 'cake', 'bird', 'cloud', 'dog', 'tomato']</code></span></span></span>
使用insert() 方法,将项目插入指定位置
在insert() 的括号内填入两个引数,第一个代表位置,第二个代表要插入的项目。
insert() 是专属于串列的方法,只能用在串列上,其他资料型态都不行。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red.insert(0, 'tomato')
>>>print(red)
['tomato', 'flower', 'blood', 'hair']</code></span></span></span>
位置如果超过串列的项目数量,会直接将要插入的值放在最后。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red.insert(10, 'tomato')
>>>print(red)
['flower', 'blood', 'hair', 'tomato']</code></span></span></span>
使用append() 方法,将项目加到串列尾端
在append() 的括号内填入要增加在串列尾端的值。
append() 是也专属于串列的方法,只能用在串列上,其他资料型态都不行。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red.append('tomato')
>>>print(red)
['flower', 'blood', 'hair', 'tomato']</code></span></span></span>
当插入的值也是串列的时候,会变怎样呢?
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red.append(['tomato', 'cake'])
>>>print(red)
['flower', 'blood', 'hair', ['tomato', 'cake']]</code></span></span></span>
跟你想的一样吗?插入的项目就是一个串列,而这样有一层一层的感觉的资料结构,就是巢状结构
串列可以容纳各种Python 的物件,在串列中放入串列也是可以的。
删除串列项目
用del 陈述句删除项目
在del 后方说明要删除的项目,在知道项目的位置(index)时,就可以在串列中把该项目删除。
del 不是函式(Function)也不是方法(Method),不需要使用括号( ),只要把要执行的动作叙述出来就可以,所以就叫del 为陈述句。
例子中,名字叫作red 的串列有5 个字串项目,我们使用del 陈述句,把位置0 的 'flower' 字串删除。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'hair', 'hair']
>>>del red[0]
>>>print(red)
['blood', 'hair', 'hair', 'hair']</code></span></span></span>
使用del 陈述句来删除项目,你需要知道项目的位置,如果不知道变无法正确的删除。
用remove() 方法删除项目
当你只记得项目是什么,但不知道位置时,可以使用remove() 方法来删除项目,在括号中填入你要删除的值即可。
如果你要删除的项目,在串列中有很多个,remove() 只能删除找到的第一个。
下方的例子中,'hair' 只被删除了一次。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'hair', 'hair']
>>>red.remove('hair')
>>>print(red)
['flower', 'blood', 'hair', 'hair']</code></span></span></span>
用pop() 方法取出项目,并删除
使用pop()方法来删除项目,也需要知道要删除的项目在哪里,位置(index)是什么?
pop() 的括号内填入位置,就可以删掉那个位置的值。
如果你什么都没有填的话,预设值式-1,Python 会把尾端的项目取出并且删除。
为什么要说取出呢,因为你印出red.pop(位置),会印出删除的项目,而不是None。
你看,下方的例子中pop() 就提取出blood,让我们可以用print() 函式把它印出来。
而 red 串列中的 blood。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'hair', 'hair']
>>>print(red.pop(1))
blood
>>>print(red)
['flower', 'hair', 'hair', 'hair']</code></span></span></span>
用clear() 方法把全部的项目删光(Python 3.3后加入)
使用clear()可以把串列中的所有项目删除,回传一个空串列。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red.clear()
>>>print(red)
[]</code></span></span></span>
用slice 删除项目
前面介绍的改变串列所使用的slice,也可以删除项目,把项目改变为空的串列就可以了。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'hair', 'hair']
>>>red[:2] = []
>>>print(red)
['hair', 'hair', 'hair']</code></span></span></span>
排序资料
运用reverse() 方法将顺序倒过来,原串列改变
串列是有顺序性的资料型态,如果你想把顺序整个颠倒过来,可以使用reverse() 方法将串列的顺序反转,原串列被改变,顺序倒过来了。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake', 'tomato']
>>>red.reverse()
>>>print(red)</code></span></span></span>
程式码执行后的结果:
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>['tomato', 'cake', 'hair', 'blood', 'flower']</code></span></span></span>
使用reversed()函式产生相反顺序的迭代器,原串列不变
想让串列顺序相反,你还可以使用reversed()函式,和前面的reverse()方法差了字尾的d,你有发现吗?
reversed()函式除了字尾多了一个d,还有两点不同点:
- reversed()函式不会改变原有串列。
- 返回的值是迭代器(iterator),需使用list()函式将之变为串列。
用相同例子来说明:
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>> red = ['flower', 'blood', 'hair', 'cake', 'tomato']
>>> newRed = list(reversed(red))
>>> print(newRed)</code></span></span></span>
程式码执行后的结果:
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>['tomato', 'cake', 'hair', 'blood', 'flower']</code></span></span></span>
用sort() 方法就地改变排序,原串列会改变
当串列中单纯只有数值或只有字串,可以使用sort() 方法改变串列的排序,预设的排序是数值由小到大,字母依「ASCII」所对应的数值,由小到大,升序排序。
从下方「ASCII」表格中,我们可以看到大写A 的内码是65(看十进位那行),小写a 的内码是97,以此类推,所以大写字母会排在小写字母之前。
如果希望降序排序,就是有大到小排序,在sort() 的括号中填入reverse = True,像这样sort(reverse = True),就可以让字串降序排序了。
先举两个单纯的排序例子,串列中只有数值:
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>number = [5, 7, 9, 1, 3, 55]
>>>number.sort()
>>>print(number)
[1, 3, 5, 7, 9, 55]</code></span></span></span>
串列中只有字串:
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair', 'cake', 'tomato']
>>>red.sort()
>>>print(red)
['blood', 'cake', 'flower', 'hair', 'tomato']</code></span></span></span>
sort 方法有三个要点要留意:
1. 会直接改变串列的排序。
2. 当串列的项目中混有数值、字串时,Python无法排序。
3. 排序的依据是「ASCII」,大写字母会排在小写字母之前,也就是小写的a 会排在大写Z 之后。
先来看看当串列中混有数值与字串时,Python会有什么反应。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>number = [5, 7, '9', 1, 3, 55]
>>>number.sort()
>>>print(number)
number.sort()
TypeError: '< ' not supported between instances of 'str' and 'int'</code></span></span></span>
果然,显示TypeError 这个错误提示,要排序的串列中,不可以混合数值与字串, '9' 是字串不是数值。
而当串列中有字母大小写不同的字串时,是怎么排列的呢?
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>letters = ['Z', 'A', 'a', 'z', 'q', 'Q']
>>>letters.sort()
>>>print(letters)
['A', 'Q', 'Z', 'a', 'q', 'z']</code></span></span></span>
Python 依据「ASCII」将大小写字母分别排序。
如果希望A、a 不论大小写,都可以排在前头,可以结合字串方法str.lower,把字母统一转换为小写让Python 去排序,当然使用str.upper 也可。
这个方式不会改变串列内的值,只是在排序时会统一将值视为小写或大写。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>letters = ['Z', 'A', 'a', 'z', 'q', 'Q']
>>>letters.sort(key = str.lower)
>>>print(letters)
['A', 'a', 'q', 'Q', 'Z', 'z']</code></span></span></span>
使用sorted() 函式回传改变后的副本,原串列不变
sorted() 函式与刚刚介绍的sort() 方法外观极为相像,只是函式多了ed。
sorted() 以升序排序,在括弧内有四个参数。
(串列, cmp比较的函数, 比较的元素key = None , 排序规则reverse = False)
cmp本文不谈,先使用其他参个变数来排序,sorted()函式并不会改变原本的串列排序,而是做一个副本进行排序。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>letters = ['Z', 'A', 'a', 'z', 'q', 'Q']
>>>print(sorted(letters, key = str.lower, reverse = True))
['Z', 'z', 'q', 'Q', 'A', 'a']
>>>print(letters)
['Z', 'A', 'a', 'z', 'q', 'Q']</code></span></span></span>
复制串列
当我们要操作串列但又不想动到串列,造成串列的改变,可以将串列的值复制后指派给一个新的变数,新的变数就会是一样的串列,就好像你平时用word 编辑文件时,另存新档的情况。
用list() 复制串列
像在建立串列一样,在list() 函式的括号中放入要复制的串列,再指派给新的变数。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red_copy = list(red)
>>>print(red)
['flower', 'blood', 'hair']
>>>print(red_copy)
['flower', 'blood', 'hair']
>>>print(id(red))
2610472
>>>print(id(red_copy))
2780008
</code></span></span></span>
用slice 复制串列
运用slice [:] 一刀不切,将串列再指派给新的变数。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red_copy = red[:]
>>>print(red)
['flower', 'blood', 'hair']
>>>print(red_copy)
['flower', 'blood', 'hair']</code></span></span></span>
用copy() 方法制作副本
使用copy() 方法(Method)复制串列,将复制后的串列指派给新的变数。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>red_copy = red.copy()
>>>print(red)
['flower', 'blood', 'hair']
>>>print(red_copy)
['flower', 'blood', 'hair']</code></span></span></span>
汇入copy 模组,用deepcopy() 函式制作深度复制的副本
有copy()这个复制的方法(Method),为何还有deepcopy() 函式呢?
(长得很像的东西又一个方法、一个函式了,考验人的记忆力阿…..)
deepcopy() 顾名思义,加了一个deep,可以想见这是一个从骨子里全部都复制起来的意思。
对于串列中还存放了串列的资料,要使用deepcopy() 才可以将串列才可以完全的复制。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', [55, 6]]
>>>red_list = list(red)
>>>red_slice = red[:]
>>>red_copy = red.copy()
>>>print(red)
>>>print(red_list)
>>>print(red_slice)
>>>print(red_copy)
['flower', 'blood', [55, 6]]
['flower', 'blood', [55, 6]]
['flower', 'blood', [55, 6]]
['flower', 'blood', [55, 6]]
</code></span></span></span>
成功复制后,只更动red[0]、red[2][0] 的值,其他三个复制red 串列的变数后变更吗?
red[2][0] 是指,red 串列中,位置1 的项目内,在位置0 的值,先找到red[1],再看这个位置的项目内位置0 的值,下方的例子中red[2][0] 是一个数值55。
我们将red[0] 改为100、red[2][0] 的值改变为数值88,刚刚复制red 的三个变数值也变动了,但只有[2][0] 的地方跟着变动,[0] 并没有变动。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red[0] = 100
>>>red[2][0] = 88
>>>print(red)
>>>print(red_list)
>>>print(red_slice)
>>>print(red_copy)
[100, 'blood', [88, 6]]
['flower', 'blood', [88, 6]]
['flower', 'blood', [88, 6]]
['flower', 'blood', [88, 6]]</code></span></span></span>
list()、slice、copy() 的复制都属于浅层的复制,当资料只有一层时,不会有问题,复制后的串列不因原本复制的本体而变动,所以red[0] 从'flower' 变为100,red_list、red_slice、red_copy 这三个串列位置0 的值仍维持不变。
但当资料多于一层时,例如串列中还包含了串列,浅层的复制无法深入到第二层以上。这样多层的概念,也称之为巢状。
这时候就需要deepcopy() ,才可以将每一个层次的资料都复制到新的变数中。
使用前你必须先汇入copy 模组,才会有deepcopy() 函式功能。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>import copy
>>>red = ['flower', 'blood', [55, 6]]
>>>red[0] = 100
>>>red[2][0] = 88
>>>print(red)
[100, 'blood', [88, 6]]
>>>print(red_deepcopy)
['flower', 'blood', [55, 6]]</code></span></span></span>
使用串列时的常见错误
索引错误
初学Python 串列(list),容易忘记位置(index)的算法是从0开始,当提取串列中的资料,指定的位置却超出范围,就会出现IndexError。
例如,在名为red的串列中,你要印出'hair'这个项目,但以为它的位置是3,导致Python 回覆你错误。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>print(red[3])
print(red[3])
IndexError: list index out of range</code></span></span></span>
out of range 就是超出范围的意思。
为什么呢?因为'hair' 的位置是2 才对。
<span style="color:#3a3a3a"><span style="background-color:#ffffff"><span style="background-color:#eeeeee"><code>>>>red = ['flower', 'blood', 'hair']
>>>print(red[2])
hair</code></span></span></span>
串列还有一个很常见的操作,是使用for 及in 制作的回圈(loop)进行迭代(iteration),你可以在这篇文章看到说明《Python for 回圈(loop)的基本认识与7种操作》,迭代串列(list)可以搭配本文的函式、串列方法运用,端看你的需求是什么啰。
如果想了解更多串列的观念与操作,推荐阅读《精通Python》、《Python自动化的乐趣》这两本书,都有单独针对字串做详细的说明及练习。