Skip to content

5 、列表


一、基础🧀

1、创建🧀

# 使用方括号 [] 直接创建列表
[2, 4, 6, 8]
# 使用 range() 创建一个范围的列表
x = list(range(50))
1
2
3
4
# 通过 append() 方法动态添加元素
my_list = []
my_list.append(1)
my_list.append(2)
  • 列表可以含有各种数据类型的元素
1
2
3
4
petInfo = ['cat', 'Tom', 14, 16.7, True] * 2    # list可以做乘法操作,和字符串类似
print(petInfo)
print(f"Type of petInfo: {type(petInfo)}")
print(f"Length of petInfo: {len(petInfo)}")

2、内建函数🧀

even = [2, 4, 6, 8]
print(f"Sum = {sum(even)},\nMin = {min(even)},\nMax = {max(even)},\nLen = {len(even)}")

3、比较🧀

1
2
3
4
5
6
7
8
a = [10, 20, 30]
b = a   # b 与 a 在内存中指向同一处,也称 b 是 a 的 alias
c = [10, 20, 30]
print(f"a==b? {a == b}")
print(f"a==c? {a == c}")

print(f"a is b? {a is b}")
print(f"a is c? {a is c}")  # False
1
2
3
4
5
6
#  如下复制操作不同于 alias
import copy
b = copy.copy(a)    # 复制操作,这时候改变 c 不影响 a
c = a[:]
d = a + [ ]
e = list(a)

4、遍历🧀

1
2
3
4
5
for item in a:
    print(item)

for i in range(len(a)):
    print(a[i])

遍历中修改列表

在 Python 中,用 for item in a 遍历列表时,其实是按 索引顺序访问每个元素的。而当你在循环中使用 a.remove(item) 删除元素时,列表的结构会立刻改变,索引顺序就乱了,导致跳过了一些元素。

1
2
3
4
5
a = [3, 3, 2, 3, 4]
for item in a:     
    if (item == 3):
      a.remove(item)
print(a) 

5、排序🧀

  • 破坏性的
1
2
3
4
5
6
7
8
a = [7, 2, 5, 3, 5, 11, 7]
print("At first, a =", a)

a.sort()
print("After a.sort(), a =", a)

a.reverse()
print(a)
  • 非破坏性的
1
2
3
4
5
6
7
a = [7, 2, 5, 3, 5, 11, 7]
b = sorted(a)
# sorted() 直接返回列表可以直接打印
print(b)
# reversed() 返回的是一个迭代器,可以在 for 循环中使用。
for item in reversed(a):
    print(item, end=" ")
操作类型 破坏性(修改原列表) 非破坏性(生成新列表)
赋值 b = a b = a[:] / copy.copy(a) / list(a)
添加元素 a.append(x) / a.extend([...]) / a += [...] a = a + [...]
删除元素 a.pop() / a.pop(i) / a.remove(x) a = a[:i] + a[i+1:]
插入元素 a.insert(i, x) a = a[:i] + [x] + a[i:]
排序 a.sort() a = sorted(a)
反转 a.reverse() a = list(reversed(a))

6、常用方法🧀

方法 说明
list.append(obj) 末尾添加新的对象
list.count(obj) 统计某个元素出现的次数
list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.index(obj) 找出某个值第一个匹配项的索引位置
list.insert(index, obj) 将对象插入指定位置
list.pop([index=-1]) 移除一个元素(默认最后一个元素),并且返回该元素的值
list.remove(obj) 移除某个值的第一个匹配项
list.reverse() 反向列表中元素
list.sort(key=None, reverse=False) 排序,key 控制排序依据,reverse 控制顺序
list.clear() 清空列表
list.copy() 复制列表,创建一个新的列表对象

※ 元组🧀

  • 元组和列表类似,只是不能修改
  • () 包裹

二、进阶🧀

1、列表推导式🧀

[expression for item in iterable if condition]
  • expression: 结果表达式(可以是任意计算,如 i*100
  • item: 遍历变量
  • iterable: 任何可迭代对象(如 range, list, string
  • if condition: 可选过滤条件
a = [(i * 100) for i in range(20) if i % 5 == 0]
squares = [x**2 for x in range(10)]

2、字符串🔁列表🧀

  • 字符串 → 列表
1
2
3
4
5
6
7
8
a = list("wahoo!")  # 使用list("")
print(a)
# 输出: ['w', 'a', 'h', 'o', 'o', '!']

s = "How are you doing today?"
a = s.split(" ")    # 使用 .split("") 方法
print(a)
# 输出: ['How', 'are', 'you', 'doing', 'today?']
  • 列表 → 字符串
1
2
3
words = ["parsley", "is", "gharsley"]
print("".join(words))   # 输出: parsleyisgharsley
print(" ".join(words))  # 输出: parsley is gharsley

三、二维列表🧀

1、创建🧀

a = [ [ 2, 3, 4 ] , [ 5, 6, 7 ] ]

Failure

使用 * 创建二维数组(产生浅拷贝)

a = [[0] * cols] * rows
  • 这个写法看起来像是创建了 rows 个不同行
  • 实际上,每一行都指向同一个内存对象,是同一行的多个别名(shallow copy)
  • 使用 append() 方法
1
2
3
a = []
for row in range(rows):
    a += [[0]*cols]  # or a.append([0]*cols)
  • 使用推导式
a = [[0]*cols for row in range(rows)]
  • 封装成函数
1
2
3
4
def make2dList(rows, cols):
    return [[0]*cols for row in range(rows)]

a = make2dList(3, 2)

2、维数🧀

1
2
3
4
5
6
a = [ [ 2, 3, 5] , [ 1, 4, 7 ] ]
print("a = ", a)

rowscols = len(a)len(a[0])
print("rows =", rows)   # 2
print("cols =", cols)   # 3

3、拷贝🧀

import copy

a = [ [ 1, 2, 3 ] , [ 4, 5, 6 ] ]

b = copy.copy(a) # Error:  shallow copy
c = copy.deepcopy(a)    # 使用deepcopy即可


print("At first...")
print("   a =", a)
print("   b =", b)


a[0][0] = 9
print("But after a[0][0] = 9")
print("   a =", a)
print("   b =", b)  # 浅拷贝导致改变 a[0][0] 时也改变 b[0][0]
对齐打印
# 辅助函数:用于查找二维列表中最长元素的字符串长度
def maxItemLength(a):
    maxLen = 0
    for row in range(len(a)):
        for col in range(len(a[row])):
            # 使用 repr() 可以兼容显示数值、字符串、布尔值、None 等各种类型
            maxLen = max(maxLen, len(repr(a[row][col])))
    return maxLen

# 打印二维列表的函数(美观格式化,并带有行列标签)
def print2dList(a):
    if a == []:
        print([])  # 空列表直接打印
        return

    rows, cols = len(a), len(a[0])  # 实际行数和第一行的列数
    maxCols = max([len(row) for row in a])  # 处理 ragged list(每行列数不同)
    fieldWidth = max(maxItemLength(a), len(f'col={maxCols-1}'))  # 每列的宽度,至少能容纳列标签
    rowLabelSize = 5 + len(str(rows-1))  # 行标签宽度,动态调整以适应行数
    rowPrefix = ' ' * rowLabelSize + ' '  # 每行前缀,用于列标题对齐
    rowSeparator = rowPrefix + '|' + ('-' * (fieldWidth + 3) + '|') * maxCols  # 每行之间的分割线

    # 打印列标题(col=0, col=1, ...),居中对齐
    print(rowPrefix, end='  ')
    for col in range(maxCols):
        print(f'col={col}'.center(fieldWidth + 2), end='  ')
    print('\n' + rowSeparator)

    # 遍历每一行并打印其内容
    for row in range(rows):
        # 打印行标签(row=0, row=1, ...)
        print(f'row={row}'.center(rowLabelSize), end=' | ')
        # 打印该行的每个元素,居中对齐
        for col in range(len(a[row])):
            print(repr(a[row][col]).center(fieldWidth + 1), end=' | ')
        # 对于 ragged list 中缺失的列,用 ✖ 填充
        missingCellChar = chr(10006)  # Unicode 编号 10006,即 ✖
        for col in range(len(a[row]), maxCols):
            print(missingCellChar * (fieldWidth + 1), end=' | ')
        print('\n' + rowSeparator)
    print()

# 示例数据
a = [ [ 1, -1023, 3 ] , [ 4, 5, 678 ] ]
b = [ [123, 4567, 891011], [567890, 'ABC'], ['Amazing!', True, '', -3.14, None]]

# 打印示例列表
print2dList(a)
print2dList(b)