列表是由一系元素按特定顺序构成的数据序列,这样就意味着定义一个列表类型的变量,可以保存多个数据,而且允许有重复的数据。
列表是容器型数据类型(用一个变量可以保存多个数据),是可变数据类型
列表用[]
来定义,列表的数据项不需要具有相同的类型:
list1 = [35, 12, 97, 55, 68, 73, 49, 92, 20] list2 = ['210502', '悾格', True, 20, '1999-12-31'] list3 = ['A', 'a', 'B', 'b', 'C'] # 查看变量的数据类型 print(type(list2)) # <class 'list'> print(type(list2[1])) # <class 'str'> print(type(list2[2])) # <class 'bool'> print(type(list2[3])) # <class 'int'>
创建列表可以从三个方面来创建:
1. 字面量语法 2. 构造器语法 - 通过Python内置的`list`函数将其他序列变成列表。准确的说,`list`并不是一个函数,而是创建列表对象的构造器 3. 生成式(推导式)语法
# 创建列表 # 方式一:字面量语法 list1 = ['apple', 'orange', 'pitaya', 'durian'] print(list1) # ['apple', 'orange', 'pitaya', 'durian'] # 方式二:构造器语法 list2 = list(range(1, 10)) # 创建一个1-9的列表 print(list2) # [1, 2, 3, 4, 5, 6, 7, 8, 9] # 方式三:生成式(推导式)语法 list3 = [i ** 2 for i in range(1, 10)] # 创建一个1-9平方的列表 print(list3) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
# 定义2个列表 list1 = [76, 83, 91, 97] list2 = [61, 26] # 列表的拼接(赋值给原有的列表并更新该列表或赋值给新的列表) list3 = list1 + list2 print(list3) # [76, 83, 91, 97, 61, 26] # 列表的重复 list4 = ['Hi'] * 3 print(list4) # ['Hi', 'Hi', 'Hi'] # 列表的成员运算(查看某个元素是否存在于该列表) print(100 in list3) # False print('Hello' not in list4) # True # 获取列表的长度(元素个数) print(len(list3)) # 6 # 列表的索引 print(list3[0], list3[-6]) # 76 76 # 同时可以通过索引来改变指定下标元素的值 list3[5] = 100 # 修改下标为5的元素的值 print(list3) # [76, 83, 91, 97, 61, 100] ''' 列表的切片(格式:list3[start:end:step]) start:列表切片初识位置,默认为0 end:列表切片终止位置,默认为列表的最后元素下标 step:步长,切片元素截取的间隔长度,值为负数时,反向切片 ''' print(list3[:5]) # [76, 83, 91, 97, 61] print(list3[4:]) # [61, 100] print(list3[-3:-6:-1]) # [97, 91, 83] print(list3[::-2]) # [100, 97, 83] # 列表的比较运算 list5 = [1, 2, 3, 4] list6 = list(range(1, 5)) # 两个列表比较相等性比的是对应索引位置上的元素是否相等 print(list5 == list6) # True list7 = [3, 2, 1] # 两个列表比较大小比的是对应索引位置上的元素的大小 print(list5 <= list7) # True
由于列表是可变类型,所以通过索引操作既可以获取列表中的元素,也可以更新列表中的元素。对列表做索引操作一样要注意索引越界的问题,对于有N
个元素的列表,正向索引的范围是0
到N-1
,负向索引的范围是-1
到-N
,如果超出这个范围,将引发IndexError
异常,错误信息为:list index out of range
。
num = [35, 98, 12, 27, 66] # 对列表进行读操作的for循环,无序号 for x in num: print(x) # 有序号,先通过enumerate函数对列表进行预处理 # 循环遍历的时候既可以获取到索引(下标)又可以获取到元素 for i, x in enumerate(num): print(i, x)
# 添加和删除元素 list1 = [12, 23, 34] # 添加元素(append()) list1.append(45) print(list1) # [12, 23, 34, 45] # 在指定位置添加元素(insert()) list1.insert(2, 56) print(list1) # [12, 23, 56, 34, 45] # 删除指定元素(remove()) list1.remove(12) print(list1) # [23, 56, 34, 45] # 删除列表最后一个元素(pop()默认删除最后一个元素) list1.pop() print(list1) # [23, 56, 34] # pop()也可以删除指定索引位置的元素 list1.pop(1) print(list1) # [23, 34] # 清空列表中的元素 list1.clear() print(list1) # []
列表类型的index
方法可以查找某个元素在列表中的索引位置;因为列表中允许有重复的元素,所以列表类型提供了count
方法来统计一个元素在列表中出现的次数。
list1 = [12, 23, 34, 45, 56, 12] # 查询元素的索引位置(index()) print(list1.index(12)) # 0 # 若需要查询的元素有2个时,需要从第一个该元素的后一位下标开始查找 print(list1.index(12, 1)) # 5 # 统计元素出现的次数 print(list1.count(12)) # 2 print(list1.count(34)) # 1 print(list1.count(78)) # 0
list1 = ['banana', 'grape', 'apple', 'waxberry', 'pitaya', 'apple'] # 排序 list1.sort() # 升序 print(list1) # ['apple', 'apple', 'banana', 'grape', 'pitaya', 'waxberry'] list1.sort(reverse=True) # 降序 print(list1) # ['waxberry', 'pitaya', 'grape', 'banana', 'apple', 'apple'] # 反转(反向索引或reverse()) # 反向索引不修改列表,reverse()函数更新列表 print(list1[::-1]) # ['apple', 'apple', 'banana', 'grape', 'pitaya', 'waxberry'] list1.reverse() print(list1) # ['apple', 'apple', 'banana', 'grape', 'pitaya', 'waxberry']
元组是多个元素按照一定顺序构成的序列,元组是容器型数据类型以及不可变类型,也就是意味着元组一旦定义,其中的元素就不能再添加或删除。
元组用( )
来定义, 元组的数据项不需要具有相同的类型:
# 空元组 a = () print(type(a)) # <class 'tuple'> # 不是元组 # 元组中只有一个元素时,千万不要忘记打逗号,不然电脑会认为是其他数据类型 b = ('hello') print(type(b)) # <class 'str'> c = (100) print(type(c)) # <class 'int'> # 一元组 d = ('hello', ) print(type(d)) # <class 'tuple'> e = (100, ) print(type(e)) # <class 'tuple'> # 定义一个三元组 t1 = (30, 10, 50) # 定义一个四元组 t2 = ('210502', '悾格', True, 20) # 查看变量的数据类型 print(type(t1)) # <class 'tuple'>
t1 = (30, 10, 50) t2 = ('210502', '悾格', True, 20) # 查看元组中元素的数量 print(len(t1), len(t2)) # 3 4 # 通过索引运算获取元组中的元素 print(t1[0], t1[-3]) # 30 30 print(t2[2], t2[-2]) # True True # 循环遍历元组中的元素 for member in t2: print(member) # 成员运算(查看某个元素是否存在于该列表) print(100 in t1) # False print(20 in t2) # True # 拼接 t3 = t1 + t2 print(t3) # (30, 10, 50, '210502', '悾格', True, 20) # 切片 print(t3[:5]) # (30, 10, 50, '210502', '悾格') print(t3[4:]) # ('悾格', True, 20) print(t3[-3:-6:-1]) # ('悾格', '210502', 50) print(t3[::-2]) # (20, '悾格', 50, 30) # 比较运算 print(t1 == t3) # False print(t1 >= t3) # False print(t1 < (30, 11, 55)) # True
当我们把多个用逗号分隔的值赋给一个变量时,多个值会打包成一个元组类型;当我们把一个元组赋值给多个变量时,元组会解包成多个值然后分别赋给对应的变量,如下面的代码所示。
# 打包 a = 1, 10, 100 print(type(a), a) # <class 'tuple'> (1, 10, 100) # 解包 i, j, k = a print(i, j, k) # 1 10 100
在解包时,如果解包出来的元素个数和变量个数不对应,会引发ValueError
异常,错误信息为:too many values to unpack
(解包的值太多)或not enough values to unpack
(解包的值不足)。
a = 1, 10, 100, 1000 # i, j, k = a # ValueError: too many values to unpack (expected 3) # i, j, k, l, m, n = a # ValueError: not enough values to unpack (expected 6, got 4)
所以为了解决这个问题,就创建了星号表达式,用星号表达式修饰的变量会变成一个列表,该列表可以是0个或多个元素。
a = 1, 10, 100, 1000 i, j, *k = a print(i, j, k) # 1 10 [100, 1000] i, *j, k = a print(i, j, k) # 1 [10, 100] 1000 *i, j, k = a print(i, j, k) # [1, 10] 100 1000 *i, j = a print(i, j) # [1, 10, 100] 1000 i, *j = a print(i, j) # 1 [10, 100, 1000] i, j, k, *l = a print(i, j, k, l) # 1 10 100 [1000] i, j, k, l, *m = a print(i, j, k, l, m) # 1 10 100 1000 []
# 变换2个变量 a, b = b, a # 变换3个变量 a, b, c = b, c, a
字符串,就是由零个或多个字符组成的有限序列
s1 = 'hello, world!' s2 = '你好,世界' print(s1, s2) # hello, world! 你好,世界 s3 = ''' hello, world! ''' print(s3, end='') '''运行结果: hello, world! '''
# 转义字符 # \b:退格 a = '\'hello,\tworld\b\'' b = "\"hello,\nworld\"" c = ''' hello, world! ''' print(a) print(b) print(c) # 原始字符串(每个字符都是它原始的含义,没有转义字符) d = r'c:\User\Administrator\abc\hello.py' print(d) # 带占位符的字符串(格式化字符串) e = f'文件路径:{d}' print(e) s1 = '\141\142\143\x61\x62\x63' print(s1) # ASCII ---> GB2312 ---> GBK ---> Unicode(UTF-8)(所有主流字符) # 字符串s1中\t是制表符,\n是换行符 s1 = '\time up \now' print(s1) '''运行结果: ime up ow ''' # 字符串s2中没有转义字符,每个字符都是原始含义 s2 = r'\time up \now' print(s2) # \time up \now
运算 | ||
---|---|---|
+ | 拼接 | s1 = ‘hello’ + ’ ’ + ‘world’ |
* | 重复 | s2 = ‘!’ * 3 |
对于两个字符串类型的变量,可以直接使用比较运算符比较两个字符串的相等性或大小。需要说明的是,因为字符串在计算机内存中也是以二进制形式存在的,那么字符串的大小比较比的是每个字符对应的编码的大小。
s1 = 'a whole new world' s2 = 'hello world' print(s1 == s2, s1 < s2) # False True print(s2 != 'Hello world') # True
字符串的比较运算比较的是字符串的内容,Python中还有一个is
运算符(身份运算符),如果用is
来比较两个字符串,它比较的是两个变量对应的字符串是否在内存中相同的位置(内存地址),简单的说就是两个变量是否对应内存中的同一个字符串。
s1 = 'hello world' s2 = 'hello world' s3 = s2 # 比较字符串的内容 print(s1 == s2, s2 == s3) # True True # 比较字符串的内存地址 print(s1 is s2, s2 is s3) # False True
Python中可以用in
和not in
判断一个字符串中是否存在另外一个字符或字符串,in
和not in
运算通常称为成员运算,会产生布尔值True
或False
,代码如下所示。
s1 = 'hello, world' print('wo' in s1) # True s2 = 'goodbye' print(s2 in s1) # False
# 获取字符串长度 s1 = 'a whole new world' print(len(s1)) # 17 a = 'hello,world!' b = 'hello,world!' # 索引 # 查找字符串a的第一个字符, print(a[0], a[-len(a)]) # h h # 查找字符串a的最后一个字符 print(a[len(a) - 1], a[-1]) # ! ! # 查找字符串a的第6个字符 print(a[5], a[-7]) # , , # 查找字符串a的第8个字符 print(a[7], a[-5]) # o o # 切片 # 返回字符串a下标为2-5的字符串 print(a[2:5]) # llo # 返回字符串a下标为1-10,但长度为2的字符串 print(a[1:10:2]) # el,ol # 对字符串a的反向切片 print(a[::-1]) # !dlrow,olleh # 反转 print(''.join(list(reversed(a)))) # !dlrow,olleh # 循环遍历 s3 = 'hello' # 一、 for index in range(len(s3)): print(s3[index]) # 二、 for ch in s3: print(ch)