<center> Python 序列 </center>


本文章总结了董付国老师的Pthon程序设计(第2版)书的内容,仅供个人学习使用,如有侵权,立刻删除     by:mfdy


文章链接:mfdy’s blog: Python 序列


CSDN目录:https://blog.csdn.net/mofadiyu/article/details/90178542

2.1 列表

2.1.1 列表的创建与删除

a_list = ['a', 'b', 'mpilgrim', 'z', 'example']
a_list = []
# 创建空列表

或者是用list()函数将元组、range对象、字符串或者其他类型的可迭代对象类型的数据转换为列表,例如:

a_list = list((3, 5, 7, 9, 11))
# [3, 5, 7, 9, 11]
list(range(1, 10, 2))
# [1, 3, 5, 7, 9]
print(list('hello world'))
# ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
x =list()
# 创建空列表

当不再使用时,使用del命令删除整个列表,如果列表对象所指向的值不再有其他对象指向,同时删除该值

del a_list
>>> a_list
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    a_list
NameError: name 'a_list' is not defined

2.1.2 列表元素的增加

  1. 可以使用 + 运算符添加,但是其实这个是重新创建一个列表,并将元素复制过来
aList = [3, 4, 5]
aList = aList + [7]
>>> aList
[3, 4, 5 ,7]
  1. 使用列表对象的append()方法,再不改变列表在内存中的首地址情况下修改列表,推荐方法
aList.append(9)
>>> aList
[3, 4, 5, 7 ,9]

Python 采用的是基于值的自动内存管理方式,当为对象修改值得时候,是使变量直接指向新的值,适用于所有类型的变量

a = [1, 2, 3]
>>> id(a)
1234567
a = [1, 2]
>>> id(a)
1234589

但如果是通过修改下标来修改序列中元素的值或者通过可变序列对象自身提供的方法来增加和删除元素的时候,序列对象在内存中的起始地址是不变的,仅仅是被修改的元素地址发生变化

a = [1, 2, 4]
b = [1, 2, 3]
>>> a == b 
False
>>> id(a) == id(b)
False
>>> id(a[0]) == id(b[0])
True
>>> id(a)
12345678
a[0] = 5
>>> id(a)
12345678
  1. extend(): 将另一个迭代对象的所有元素添加至该列表对象的尾部
a = [1, 2, 3]
>>> id(a)
12345678
a.extend([7, 8, 9])
>>> a
[1, 2, 3, 7, 8, 9]
>>> id(a)
12345678
  1. insert(i, j): 在列表的第i个位置插入j元素
aList.insert(3, 6)
>>> aList
[1, 2, 3, 6, 4]
  1. 使用乘法来扩展列表,将列表与整数相乘,生成一个新的列表,但是只是引用已有对象,当修改其中的一个值的时候,相关引用都会被修改
aList = [1, 2, 3]
bList = aList
>>> id(aList) == id(bList)
True
aList = aList * 2
>>> aList
[1, 2, 3, 1, 2, 3]
>>> id(aList) == id(bList)
False

x = [[asd] * 2] * 2
>>> x
[[asd, asd], [asd, asd]]
x = [1, 2, 3] * 3
x[0][0] = 5
>>> x
[[5, 2, 3], [5, 2, 3], [5, 2, 3]]

2.1.3 列表元素的删除

  1. 使用del命令删除列表或者列表中的指定位置上的元素
aList = [1, 2, 3, 4, 5]
del aList[0]
>>> aList
[2, 3, 4, 5]
del aList
>>> aList
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    a_list
NameError: name 'a_list' is not defined
  1. pop(): 删除并返回指定位置的元素,没有则默认为最后一个,如果超出范围则抛回异常
aList = list((1, 2, 3, 4, 5))
aList.pop(1)
aList.pop()
>>> aList
[1, 3, 4]
  1. remove(): 删除首次出现的指定元素,不存在则返回异常
aList = [1, 2, 3, 2, 4]
aList.remove(2)
>>> aList
[1, 3, 2, 4]

2.1.4 列表元素访问与计数

可以使用下标直接访问,如果不存在则抛出异常

aList = [1, 2, 3, 4, 5, 6]
>>> aList[3]
4
>>> aList[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

index(i): 找到元素i首次出现时的下标
count(i): 统计指定元素i在列表对象中出现的次数

aList = [3, 1, 1, 2]
>>> aList.count(1)
2
>>> aList.index(1)
1

2.1.5 成员资格判断

  1. count(): 大于0成立
  2. in 关键词
aList = [1, 2, 3, 4, 5]
bList =['a', 'b', 'c', 'd']
cList = [[1], [2], [3]]
>>> 3 in aList
True
>>> [3] in cList
True
>>> (1, 'a') in zip(aList, bList)
True

★2.1.6 切片操作

切片使用2个冒号分隔的3个数字来完成: [x:y:z]
 x表示切片开始的位置,默认为0
 y表示切片截止的为,默认为列表长度
 z表示切片的步长,默认为1

aList = [1, 2, 3, 4, 5, 7, 9, 11]
>>> aList[::]
[1, 2, 3, 4, 5, 7, 9, 11]
>>> aList[::-1]
[11, 9, 7, 5, 4, 3, 2, 1]
>>> aList[1::2]
[2, 4, 7, 11]
>>> aList[1:100:2]
[2, 4, 7, 11]
>>> aLIst[100:]
[]

注意:切片操作在程序中书写时如果要更改,则需要进行赋值操作

aList = [1, 2, 3, 4, 5, 7, 9, 11]
aList[1::2]
print(aList)
aList = aList[1::2]
print(aList)
# 输出内容
[1, 2, 3, 4, 5, 7, 9, 11]
[2, 4, 7, 11]

可以使用切片原地地址修改列表内容

aList = [3, 5, 7]

# 在尾部追加元素
aList[len(aList):] = [9]
>>> aList
[3, 5, 7, 9]

# 替换前3个元素
aList[:3] = [1, 2, 3]
>>> aList
[1, 2, 3, 9]

# 删除前3个元素
aList[:3] = []
>>> aList
[9]

# 生成0-9的十个数
aList = list(range(10))
>>> aList
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 替换偶数位置上的元素
aList[::2] = [0] * 5
>>> aList
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]

# 切片不连续,两个元素个数必须一样多
aList[::2] = [0] * 3
line 13, in <module>
    aList[::2] = [0]*3
ValueError: attempt to assign sequence of size 3 to extended slice of size 5

# del指令删除元素
aList = [3,5,7,9,11]
#删除前3个元素
del aList[:3]
#删除偶数位置上的元素
del aList[::2]

切片返回的是列表元素的浅复制
 浅复制即把原列表所有元素的引用都复制到新列表中,如果只包含数字等基本元素或者元组、字符串这样的不可变类型的数据,进行修改操作不影响原列表
 如果原列表中包含列表等可变数据类型,修改任何一个都会影响到另一个

aList = [1, 2, 3]
bList = aList[::]
>>> aList == bList
True
>>> aList is bList
False
>>> id(aList) == id(bList)
False
bList[1] = 8
>>> bList
[3, 8, 7]
>>> aList
[3, 5, 7]

aList = [[1, 2], [3, 4], [5, 6]]
bList = aList[::]
>>> id(aList) == id(bList)
False
aList[0][0] = 8;
>>> aList
[[8, 2], [3, 4], [5, 6]]
>>> bList
[[8, 2], [3, 4], [5, 6]]

2.1.7 列表排序

  1. sort(): 进行原地址排序,为自身进行更改,不需要赋值操作
import random
aList = [1, 2, 3, 4, 5, 6, 11, 12, 13]
# 将序列的所有元素进行随机排序
random.shuffle(aList)
>>> aList
[13, 5, 12, 3, 2, 6, 4, 11, 1]

# 升序排序
aList.sort()
# 降序排列
aList.sort(reverse = True)
>>> aList
[13, 12, 11, 6, 5, 4, 3, 2, 1]
# 按转化成字符串的长度排序
aList.sort(key = lambda x:len(str(x)))
[6, 5, 4, 3, 2, 1, 13, 12, 11]
  1. sorted(): 排序并返回新列表
aList = [13, 5, 12, 3, 2, 6, 4, 11, 1]
aList = sorted(aList)
>>> aList
[1, 2, 3, 4, 5, 6, 11, 12, 13]
aList = sorted(aList, reverse = True)
>>> aList
[13, 12, 11, 6, 5, 4, 3, 2, 1]
  1. reverse(): 将函数自身翻转,不需要赋值
aList = [6, 5, 4, 3, 2, 1, 13, 12, 11]
aList.reverse()
>>> aList
[11, 12, 13, 1, 2, 3, 4, 5, 6]
  1. reversed(): 翻转并返回迭代对象
aList = [11, 12, 13, 1, 2, 3, 4, 5, 6]
# 返回reversed对象
bList = reversed(aList)
>>> bList
<list_reverseiterator object at 0x0000011BE35B86D8>

# 把reversed对象转换成列表
bList = list(bList)
>>> bList
[6, 5, 4, 3, 2, 1, 13, 12, 11]
for i in bList:
    print(i, end=' ')
# 没有输出内容

# 重新创建reversed对象
bList = reversed(aList)
for i in bList:
    print(i, end=' ')
6 5 4 3 2 1 13 12 11

reversed()返回的是一个迭代器对象,只能进行一次循环遍历。显示一次所包含的值!

2.1.8 列表常用内置函数

函数 说明
list.append(x) 将元素x添加至列表尾部
list.extend(x) 将列表L中的所有元素添加值列表尾部
list.insert(index, x)   在列表指定位置index处添加元素x,该位置后面的所有元素后移一个位置
list.remove(x) 在列表中删除首次出现的元素x,该元素之后的所有元素前移一个位置
list.pop([index]) 删除并返回列表中下标为index(默认为-1)的元素
list.clear() 删除列表中所有元素,但保留列表对象
list.index(x) 返回列表中第一个值为x的元素的下标,若不存在值为x的元素则抛出异常
list.count(x) 返回指定元素x在列表中的出现次数
list.reverse() 对列表lst所有元素进行逆序
list.sort() 对列表lst中的元素进行排序,key用来指定排序依据,reverse决定升序(False)还是降序(True)
list.copy() 返回列表lst的浅复制
函数 说明
len(list) 返回列表中的元素个数,适用于元组、字典、集合、字符串等
max(list) 返回列表中的最大元素,适用于元组、字典、集合、字符串等
len(list) 返回列表中的最小元素,适用于元组、字典、集合、字符串等
sum(list) 对列表的元素进行求和运算,对非数值型列表运算需要指定start参数,同样适用于元组、range
zip() 返回可迭代的zip对象
enumerate(list)  枚举列表元素,返回枚举对象,其中每个元素为包含下标和值的元组。该函数对元组、字符串同样有效。
# sum()
  # sum()函数的start参数默认为0
  >>> sum(range(1, 11))
  55
  # 指定start参数为5,等价于5+sum(range(1,11))
  >>> sum(range(1, 11), 5)
  60
  #这个操作占用空间较大,慎用
  >>> sum([[1, 2], [3], [4]], [])
  [1, 2, 3, 4]

# zip()
  aList = [1, 2, 3]
  bList = [4, 5, 6]
  cList = zip(a, b)
  # 返回zip对象
  >>> cList
  <zip object at 0x0000000003728908>
  # 把zip对象转换成列表
  >>> list(cList)
  [(1, 4), (2, 5), (3, 6)]

# enumerate()
  for item in enumerate('abcdef'):
  	print(item)
  (0, 'a')
  (1, 'b')
  (2, 'c')
  (3, 'd')
  (4, 'e')
  (5, 'f')

2.1.9 列表推导式

aList = [x * x for x in range(10)]

等价于

aList = []
for x in range(10):
  aList.append(x*x)

也等价于

aList = list(map(lambda x: x*x, range(10)))

例:阿凡提与国王比赛下棋,国王说要是自己输了的话阿凡提想要什么他都可以拿得出来。阿凡提说那就要点米吧,棋盘一共64个小格子,在第一个格子里放1粒米,第二个格子里放2粒米,第三个格子里放4粒米,第四个格子里放8粒米,以此类推,后面每个格子里的米都是前一个格子里的2倍,一直把64个格子都放满。需要多少粒米呢?

print(sum([2**i for i in range(64)]))

例1. 使用列表推导式实现嵌套列表的平铺

vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
aList = [num for elem in vec for num in elem]
>>> aList
[1, 2, 3, 4, 5, 6, 7, 8, 9]

相当于

vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
result = []
for elem in vec:
    for num in elem:
        result.append(num)
>>> result
[1, 2, 3, 4, 5, 6, 7, 8, 9]

# 或者
vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
result = sum(vec, [])
>>> result
[1, 2, 3, 4, 5, 6, 7, 8, 9]

# chain()可以把一组迭代对象串联起来,形成一个更大的迭代器
vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
from itertools import chain
result = list(chain(*vec))
>>> result
[1, 2, 3, 4, 5, 6, 7, 8, 9]

例2. 列出当前文件夹下所有Python源文件

>>> import os
>>> [filename for filename in os.listdir('.') if filename.endswith(('.py', '.pyw'))]

例3. 过滤不符合条件的元素

>>> aList = [-1,-4,6,7.5,-2.3,9,-11]
>>> [i for i in aList if i>0]
[6, 7.5, 9]