python成长之路【第二篇】:列表和元组
1、数据结构
数据结构是通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以是数字或者字符,甚至可以是其他数据结构。在Python中,最基本的数据结构是序列(sequence)。序列中的每个元素被分配一个序号--即元素的位置,也称为索引。第一个索引是0,第二个则是1,以此类推。序列中的最后一个元素索引为-1,倒数第二个元素索引为-2。
python常用的组合数据类型:
序列类型:
列表:使用[]创建,如['call','me','ishmeal',',']
元组:使用()创建,如('one','two')
字符串也属于序列类型
集合类型:
集合
映射类型:
字典
Python核心数据类型:
类型转换:
str(),repr()或format():将非字符型数据转换为字
int():转为整数
float():转为浮点
list(s):将字符串s转为列表
tuple(s):将字符串s转为元组
set(s):将字串s转为集合
fronzenset(s):将字串s转为不可变集合
dict(d):创建字典,其中d必须是(key,value)的元组序列
2、序列概述
python包含了6种内建的序列,分别为列表、元组、字符串、unicode字符串、buffer对象和xrange对象。
其中,列表可变序列,元组是不可变序列。
Python中,组合数据类型也是对象,因此其可以嵌套['hello','world',[1,2,3]]。
实质上,列表和元组并不真正存储数据,而是存放对象引用。
元组、列表以及字符串等数据类型是"有大小的",也即,其长度可使用内置函数len()测量。
3、通用序列操作
所有序列类型都可以进行某些特定的操作:
索引(indexing)
分片(slicing)
加(adding)
乘(multiplying)
检查某个元素是否属于序列的成员(成员资格)
计算序列长度len()
找出最大元素max()
找出最小元素min()
3.1、索引
序列中的所有元素都是有编号的--从0开始递增。这些元素可以通过编号分别访问。
示例:
>>> greeting = "hello" >>> greeting[0] 'h'
注意:字符串就是一个由字符组成的序列。索引0指向第1个元素,这里是字母h。
3.2、分片
与使用索引来访问单个元素类似,可以使用分片操作来访问一定范围内的元素。分片通过冒号隔开的两个索引来实现:第一个索引的元素是包含在分片内的,而第2个则不包含在分片内。相当于数学中的[x:y)。
示例:
>>> numbers = [1,2,3,4,5,6,7,8,9,10] >>> numbers[3:6] [4, 5, 6] >>> numbers[0:1] 等价于 numbers[:1] [1] >>> numbers[:1] #起始索引省略,表示从索引为0的元素开始 [1] >>> numbers[-3:-1] #从后向前取,-1表示最后一个元素。 [8, 9] >>> numbers[-3:] #末尾索引省略,表示到最后一个元素,并包括最后一个元素。 [8, 9, 10] >>> numbers[:] #两个索引都置空,表示整个序列。 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
更大的步长:
进行分片的时候,分片的开始和结束点需要进行指定(不管是直接还是间接)。而另外一个参数--步长(step length),通常是隐式设置的。默认步长为1。分片操作就是按照这个步长逐个遍历序列的元素,然后返回开始和结束点之间的所有元素。
示例:
>>> numbers = [1,2,3,4,5,6,7,8,9,10] >>> numbers[::2] [1, 3, 5, 7, 9]
当然,步长可以是负数,此时分片从右到左提取元素。步长不能为0。
3.3、序列相加
通过使用运算符可以进行序列的连接操作,前提是相加的两个序列类型要相同。
示例:
>>> "hello," + "world!" 'hello,world!' >>> [1,2,3] + ["x","y","z"] [1, 2, 3, 'x', 'y', 'z']
3.4、乘法
用数字x乘以一个序列会生成新的序列,而在新的序列中,原来的序列将被重复x次。
示例:
>>> "hello" * 3 'hellohellohello' >>> [1,2,3] * 3 [1, 2, 3, 1, 2, 3, 1, 2, 3]
None是一个python的内建值,表示这里面没有放置任何元素。
初始化一个长度为10的列表,表示为:
>>> sequence = [ None ] * 10 >>> sequence [None, None, None, None, None, None, None, None, None, None]
3.5、成员资格
为了检查一个值是否在序列中,可以使用in运算符。这个运算符检查某个条件是否为真,然后返回相应的值:条件为真返回True,条件为假返回False。这样的运算符叫做布尔运算符,而返回的值叫做布尔值。
示例:
>>> permissions = "rw" >>> "r" in permissions True >>> "x" in permissions False >>> users = ["tom","jerry","chen"] >>> input("Enter your user name:") in users Enter your user name:chen True
3.6、长度、最小值和最大值
len()函数返回序列中所包含元素的数量
min()函数返回序列中最小的元素
max()函数返回序列中最大的元素
示例:
>>> numbers = [1,22,333] >>> len(numbers) 3 >>> max(numbers) 333 >>> min(numbers) 1
4、列表list
4.1、list函数
因为字符串不能像列表一样被修改,所以有时根据字符串创建列表会很有用。
示例:
>>> list("hello") ['h', 'e', 'l', 'l', 'o']
注意:list函数适用于所有类型的序列,而不只是字符串。
反向操作:将列表转换为字符串。其中双引号为分隔符,这里表示不使用任何分隔符。
>>> "".join(somelist) 'hello'
4.2、基本的列表操作
列表可以使用所有适用于序列的标准操作,如索引、分片、连接和乘法。下面介绍一些可以改变列表的方法:元素赋值、元素删除、分片赋值以及列表方法(请注意,并不是所有的列表方法都真正的改变列表)。
修改列表:元素赋值
使用索引标记来为某个特定的、位置明确的元素赋值。
示例:
>>> numbers = [1,22,333] >>> numbers[0] = "x" >>> numbers ['x', 22, 333]
删除元素:
方法1:使用del语句来实现
示例:
>>> numbers = [1,22,333] >>> del numbers[0] >>> numbers [22, 333]
方法2:使用list.remove()函数实现
语法:
L.remove(value) -> None -- remove first occurrence of value.
示例:
>>> numbers.remove(22) >>> numbers [333]
方法3:使用list.pop()函数实现
语法:
L.pop([index]) -> item -- remove and return item at index (default last).
示例:
>>> numbers.pop() 333 >>> numbers []
分片赋值:
分片是一个非常强大的特性,分片赋值操作则更加显现它的强大。
分片赋值语句可以在不需要替换任何原有元素的情况下插入新的元素。
示例:
>>> name = list("chen") >>> name ['c', 'h', 'e', 'n'] >>> name[2:] = list("chinese") >>> name ['c', 'h', 'c', 'h', 'i', 'n', 'e', 's', 'e'] >>> numbers = [1,5] >>> numbers[1:1] = [2,3,4] >>> numbers [1, 2, 3, 4, 5]
4.3、列表方法
方法是一个与某些对象有紧密联系的函数,对象可能是列表、数字,也可能是字符串或者其他类型的对象。一般来说,方法可以这样进行调用:
对象.方法(参数)
除了对象被放置到方法名之前,并且两者之间用一个点号隔开,方法调用与函数调用很类似。
追加:list.append方法用于在列表末尾追加新的对象。
注意:list.append方法和其他一些方法类似,只是在恰当位置修改原来的列表。这意味着,它不是简单的返回一个修改过的新列表--而是直接修改原来的列表。
示例:
>>> numbers = [1,2,3] >>> numbers.append(4) >>> numbers [1, 2, 3, 4]
插入:list.insert方法用于将对象插入到列表中。
语法:
L.insert(index, object) -- insert object before index
示例:
>>> numbers = [1,2,3,5,6] >>> numbers.insert(3,"four") >>> numbers [1, 2, 3, 'four', 5, 6]
统计:list.count方法统计某个元素在列表中出现的次数。
语法:
L.count(value) -> integer -- return number of occurrences of value
示例:
>>> x = [1,2,3,2,4,5,6,3] >>> x.count(3) 2
扩展:list.extend方法可以在列表的末尾一次性追加另一个序列中的多个值。换句话说,可以用新列表扩展原有的列表。
语法:
L.extend(iterable) -> None -- extend list by appending elements from the iterable
这个操作看起来很像连接操作,两者最主要区别在于:extend方法修改了被扩展的序列。而原始的连接操作则不然,它会返回一个全新的列表:
示例:
>>> a = [1,2,3] >>> b = [4,5,6] >>> a.extend(b) >>> a [1, 2, 3, 4, 5, 6]
索引:list.index方法用于从列表中找出某个值第一个匹配项的索引位置。
语法:
L.index(value, [start, [stop]]) -> integer -- return first index of value.
示例:
>>> name = ["tom","jerry","chen"] >>> name.index("chen") 2
排序:list.sort方法用于在原位置对序列进行排序。在"原位置排序"意味着改变原来的列表,从而让其中的元素能按一定的顺序排列,而不是简单返回一个已排序的列表副本。
语法:
L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
示例:
>>> numbers = [3,4,1,2,6] >>> numbers.sort() >>> numbers [1, 2, 3, 4, 6]
反向排列:list.reverse方法用于将列表中的元素反向存放。
语法:
L.reverse() -- reverse *IN PLACE*
示例:
>>> numbers.reverse() >>> numbers [6, 4, 3, 2, 1]
列表复制:
方法一:使用list.copy(),通过我们对拷贝前后的变量分析,list.copy方法是完全拷贝了names的数值,但是如果列表中包含列表的引用,那么list.copy也同样也会拷贝那个引用位置,换句话说,就是列表中的列表被拷贝前后一起引用。
如图:
示例:
>>> names = ["tom","jerry","chen",1,2,3] >>> names_copy = names.copy() >>> names_copy ['tom', 'jerry', 'chen', 1, 2, 3] >>> id(names) 140218837499720 >>> id(names_copy) 140218793882440
方法二:使用copy模块
示例:
>>> names = ["tom","jerry","chen",1,2,3] >>> >>> import copy #列表的深度复制,两个列表的内存地址不一样,而不是指向同一个列表的内存地址。 >>> names_copy2 = copy.deepcopy(names) >>> names_copy2 ['tom', 'jerry', 'chen', 1, 2, 3]
方法三:
>>> names = ["tom","jerry","chen",1,2,3] >>> names_copy3 = names[:] >>> id(names) 140218837499720 >>> id(names_copy3) 140218793612296
5、元组:不可变序列
元组与列表一样,也是一种序列。唯一的不同是元组不能修改。(字符串也是如此。)创建元组的语法很简单:如果你用逗号分隔了一些值,那么你就自动创建了元组。
>>> a = (1,2,3)
那么如何实现一个值得元组--必须加个逗号。
>>> 44,
(44,)
5.1、tuple函数
tuple函数的功能与list函数基本上是一样的:以一个序列作为参数并把它转换为元组。
>>> tuple([1,2,3]) (1, 2, 3) >>> tuple("abc") ('a', 'b', 'c')
5.2、基本元组操作
元组除了创建和访问元素之外,也没有太多其他操作。
元组不可替代的原因:
元组可以在映射(和集合的成员)中当做键使用--而列表则不行。
元组作为很多内建函数和方法的返回值存在,也就是说你必须对元组进行处理。只要不尝试修改元组,那么,"处理"元组在绝大多数情况下就是把他们当做列表来进行操作(除非需要使用一些元组没有的方法,例如index和count)。