python中列表(list)原理及其操作

本文详细介绍了Python中的列表数据结构,包括其原理、动态数组特性、内存管理、与数组和链表的比较,以及各种操作方法,如创建、访问、修改、删除、排序和高级列表推导式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

列表

简介

在Python中,列表(List)是一种基本的数据结构,它是一个有序的集合,可以包含重复的元素,并且能够存储不同类型的数据项(例如,整数、字符串、甚至其他列表)。列表是可变的(Mutable),这意味着你可以在创建列表后修改它的内容。

列表是Python中非常重要且功能强大的数据结构,支持多种操作,包括迭代、排序和嵌套等。正确使用列表可以使得代码更加简洁、高效。

原理

Python中的列表(List)是一种动态数组,但与其他语言中的传统数组相比,它们更加灵活和强大。要理解列表的工作原理,我们需要了解几个关键点:

动态数组的概念

  1. 动态大小:Python列表不需要事先声明大小。你可以随时添加或删除元素,列表会自动调整其大小以适应内容。

  2. 内存分配:在底层,Python列表使用连续的内存块来存储数据。当你创建一个空列表或添加元素到列表中时,Python解释器会分配一块内存给这个列表。如果继续添加元素超过了当前分配的内存大小,列表会自动重新分配一个更大的内存块来容纳更多的元素,然后将原来的元素复制到新的内存块中。这个过程是自动的,对用户来说是透明的。

  3. 时间复杂度:由于动态数组的特性,列表的操作具有不同的时间复杂度。例如,末尾添加元素(append)是常数时间复杂度(O(1)),因为它只需要将新元素放在列表的末尾。但是,如果在列表的开头插入元素,则所有后续的元素都需要向后移动一位,这个操作的时间复杂度是线性的(O(n)),其中n是列表的长度。

列表的优化

Python的列表实现对常见操作进行了优化。例如,当列表增长时,解释器不仅仅为一个新元素分配内存,而是分配一块比当前需求稍大的内存区域。这意味着随后的几次append操作不需要重新分配内存,从而提高效率。这种策略称为“过剩分配”(overallocation),是一种空间换时间的优化策略。

列表与其他数据结构的比较

  • 数组:与固定大小的数组相比,列表更加灵活,可以动态地添加和删除元素。但是,这种灵活性也意味着列表在某些操作上可能比固定大小的数组慢。
  • 链表:与链表相比,列表通过使用连续的内存块,可以提供更快的元素访问时间(因为它支持随机访问),但在插入和删除(特别是在列表中间)时可能不如链表高效。

总的来说,Python列表是一种非常通用的数据结构,适用于大多数情况,除非你的应用场景需要特别关注某些操作的性能。在这种情况下,可能需要考虑其他数据结构,如元组(Tuple)、集合(Set)或字典(Dictionary),或者使用专门的数据结构库,如NumPy数组,这些都是根据特定需求优化的。

操作

创建列表

列表可以通过将元素放在方括号[]中,用逗号分隔来创建。

my_list = [1, "Hello", 3.14, [1, 2, 3]]

访问列表元素

列表元素可以通过索引来访问,索引从0开始。

print(my_list[1])  # 输出: Hello

还可以使用负索引,-1表示最后一个元素,-2表示倒数第二个元素,以此类推。

print(my_list[-1])  # 输出: [1, 2, 3]

修改列表元素

由于列表是可变的,你可以修改其元素。

my_list[1] = "World"
print(my_list)  # 输出: [1, "World", 3.14, [1, 2, 3]]

列表切片

切片操作允许你获取列表的一部分。

print(my_list[1:3])  # 输出: ['World', 3.14]

列表追加和扩展

  • 使用append()方法在列表末尾添加一个元素。
  • 使用extend()方法可以将另一个集合中的元素逐一添加到列表中。
my_list.append(100)
my_list.extend([200, 300])

删除列表元素

  • 使用remove()方法删除列表中的特定元素。
  • 使用pop()方法删除指定位置的元素(默认是最后一个元素)。
my_list.remove("World")
last_item = my_list.pop()

列表排序

列表提供了sort()方法对列表进行原地排序。

numbers = [3, 1, 4, 1, 5, 9, 2]
numbers.sort()
print(numbers)  # 输出: [1, 1, 2, 3, 4, 5, 9]

列表推导式

列表推导式提供了一种简洁的方式来创建列表。

squares = [x**2 for x in range(10)]

列表长度

使用len()函数可以获取列表的长度。

print(len(my_list))

检查元素是否在列表中

可以使用in关键字来检查元素是否存在于列表中。

if "Hello" in my_list:
    print("Hello is in the list")

操作示例

"""
在Python中,列表是一种数据结构,可以包含任何类型的项,例如数字、字符串、其他列表等。
列表是有序的,这意味着它们的元素有特定的顺序,可以通过索引访问。
"""

# 创建列表
list1 = ['a', 'b', 'c', 'd']
print(f"list1 ==> {list1}")

# 列表的元素可以混合不同数据类型
list2 = [1, 2, 3, 4, '中文字符串', [1.1, 3.3], None]
print(f"list2 ==> {list2}")

# 追加元素
list1.append('test_append_element')
print(f"追加元素:list1 ==> {list1}")

# 获取元素
print("获取list1的索引为0的元素:" + list1[0])

# 修改元素
list1[0] = 'test_modify_element'
print(f"修改元素:list1 ==> {list1}")

# 删除元素
del list1[1]
list1.remove('c')  # 删除找到的第一个元素,找不到就报错
print(f"删除元素:list1 ==> {list1}")

# 删除并返回元素
print("删除并返回元素:" + list1.pop(1))  # 删除并返回索引为1的元素,默认删除最后一个元素
print(f"删除元素:list1 ==> {list1}")

# 列表的切片
print(f"列表的切片:{list2[0:2]}")  # 生成一个新的列表,不会改变原列表
print(f"列表的切片:list2 ==> {list2}")

# 列表的拼接,生成一个新的列表
list3 = list1 + list2
print(f"列表的拼接1,生成一个新的列表:list3 ==> {list3}")

# 列表的拼接2,修改原列表
list1.extend(list2)
print(f"列表的拼接2,修改原列表:list1 ==> {list1}")
print(f"列表的拼接2,修改原列表:list2 ==> {list2}")

# 列表的反转
list1.reverse()
print(f"列表的反转,修改原列表:list1 ==> {list1}")
# 列表的反转
print(f"列表的反转,不修改原列表:list1 ==> {list1[::-1]}")

# 元素是否在列表中
print(f"元素是否在列表中:{1 in list1}")

# 判断元素在列表中的索引
print(f"判断元素在列表中的索引:{list1.index(1)}")

高级操作

Python列表提供了一系列高级操作,使得处理数据变得更加高效和灵活。以下是一些较为高级的列表操作:

1. 列表推导式(List Comprehensions)

列表推导式是一种简洁创建列表的方法,它可以用来生成列表,过滤列表中的元素,或者对列表中的元素进行操作。

# 生成0到9每个数字的平方的列表
squares = [x**2 for x in range(10)]

# 过滤出列表中的偶数
evens = [x for x in range(10) if x % 2 == 0]

# 对列表中的元素进行操作
fruits = ["apple", "banana", "cherry"]
upper_fruits = [fruit.upper() for fruit in fruits]

2. 嵌套列表推导式

列表推导式可以嵌套,用于生成或操作多维列表。

# 生成一个3x3的矩阵
matrix = [[j for j in range(3)] for i in range(3)]
# 输出 matrix ==> [[0, 1, 2], [0, 1, 2], [0, 1, 2]]

3. 列表的zip函数

zip函数用于将多个列表对应位置的元素打包成一个个元组,然后返回由这些元组组成的列表。这对于同时遍历多个列表非常有用。

names = ["Alice", "Bob", "Charlie"]
scores = [85, 90, 88]

for name, score in zip(names, scores):
    print(f"{name}: {score}")
"""
输出:
Alice: 85
Bob: 90
Charlie: 88
"""

4. 列表的enumerate函数

enumerate函数用于在遍历列表时同时获取元素的索引和值,这在需要索引时非常有用。

for index, name in enumerate(names):
    print(f"{index}: {name}")

5. 列表的filter函数

filter函数用于过滤列表中的元素,只留下符合条件的元素。

# 过滤出列表中的偶数
evens = list(filter(lambda x: x % 2 == 0, range(10)))

6. 列表的map函数

map函数用于对列表中的所有元素应用一个函数。

# 将列表中的每个元素乘以2
doubles = list(map(lambda x: x * 2, range(10)))

7. 列表的reduce函数

reduce函数用于对列表中的元素进行累积操作,比如累加、累乘等。它不是列表的内置函数,需要从functools模块导入。

from functools import reduce

# 计算列表中元素的总和
total = reduce(lambda x, y: x + y, range(10))

8. 列表的切片赋值

列表的切片赋值可以一次性替换列表中的一段元素。

a = [1, 2, 3, 4, 5]
a[2:4] = [0, 0]
# a 现在是 [1, 2, 0, 0, 5]

练习

对数据进行分组,分组规则如下:
    1. 80分以上为一组
    2. 60-79分为一组
    3. 40-59分为一组
    4. 20-39分为一组
    5. 20分以下为一组
stu_list = [['李渊', 82], ['李世民', 7], ['侯君集', 5], ['李靖', 58], ['魏征', 41], ['房玄龄', 64], ['杜如晦', 65], ['柴绍', 94],
            ['程知节', 45], ['尉迟恭', 94], ['秦琼', 54], ['长孙无忌', 85], ['李存恭', 98], ['封德彝', 16], ['段志玄', 44], ['刘弘基', 18],
            ['徐世绩', 86], ['李治', 19], ['武则天', 39], ['太平公主', 57], ['韦后', 76], ['李隆基', 95], ['杨玉环', 33], ['王勃', 49],
            ['陈子昂', 91], ['卢照邻', 70], ['杨炯', 81], ['王之涣', 82], ['安禄山', 18], ['史思明', 9], ['张巡', 15], ['雷万春', 72],
            ['李白', 61], ['高力士', 58], ['杜甫', 27], ['白居易', 5], ['王维', 14], ['孟浩然', 32], ['杜牧', 95], ['李商隐', 34],
            ['郭子仪', 53], ['张易之', 39], ['张昌宗', 61], ['来俊臣', 8], ['杨国忠', 84], ['李林甫', 95], ['高适', 100], ['王昌龄', 40],
            ['孙思邈', 46], ['玄奘', 84], ['鉴真', 90], ['高骈', 85], ['狄仁杰', 62], ['黄巢', 79], ['王仙芝', 16], ['文成公主', 13],
            ['松赞干布', 47], ['薛涛', 79], ['鱼玄机', 16], ['贺知章', 20], ['李泌', 17], ['韩愈', 100], ['柳宗元', 88],
            ['上官婉儿 五代十国:朱温', 55], ['刘仁恭', 6], ['丁会', 26], ['李克用', 39], ['李存勖', 11], ['葛从周', 25], ['王建', 13],
            ['刘知远', 95], ['石敬瑭', 63], ['郭威', 28], ['柴荣', 50], ['孟昶', 17], ['荆浩', 84], ['刘彟', 18], ['张及之', 45],
            ['杜宇', 73], ['高季兴', 39], ['喻皓', 50], ['历真', 70], ['李茂贞', 6], ['朱友珪', 7], ['朱友贞', 11], ['刘守光', 2]]

"""
对以上数据进行分组,分组规则如下:
    1. 80分以上为一组
    2. 60-79分为一组
    3. 40-59分为一组
    4. 20-39分为一组
    5. 20分以下为一组
"""

# 1. 创建5个空列表
new_stu_list = [
    [],
    [],
    [],
    [],
    [],
]

# 2. 遍历列表
for stu in stu_list:
    if stu[1] >= 80:
        new_stu_list[0].append(stu)
    elif stu[1] >= 60:
        new_stu_list[1].append(stu)
    elif stu[1] >= 40:
        new_stu_list[2].append(stu)
    elif stu[1] >= 20:
        new_stu_list[3].append(stu)
    else:
        new_stu_list[4].append(stu)

# 3. 打印分组结果
print("80分以上:", new_stu_list[0])
print("60-79分:", new_stu_list[1])
print("40-59分:", new_stu_list[2])
print("20-39分:", new_stu_list[3])
print("20分以下:", new_stu_list[4])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿-瑞瑞

打赏不准超过你的一半工资哦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值