5分钟带你了解Python中的容器型数据类型--列表2

Python列表技巧
本文深入浅出地介绍了Python中列表的索引、切片及遍历等核心操作技巧,通过实例帮助读者快速掌握列表的基本用法。

5分钟带你了解Python中的容器型数据类型–列表2

这里,我们主要介绍的是列表的遍历列表的索引和切片列表的经典例题,想要了解更基础的知识,请前往《5分钟带你了解Python中的容器型数据类型–列表1》,废话不多说,直接进入正题

1.列表的索引和切片

这部分内容很简单,不管你是不是搞计算机的,但是既然你点到了这里,相信,你或多或少听说过索引这个词儿,如果还真没听说过,那你听过检索这个吧,现实生活中,检索的目的是查找并取出满足要求的东西,那么,其实索引和检索的过程是很像的,也就是去查找并将需要的东西取出来,而这里在列表中检索便叫做索引(我是这样理解的),那么既然索引就是这样简单的操作,想想是不是就觉得它会简单了。

  • 列表的索引

对一个列表做索引操作,语法是

列表名[元素下标]

例如:

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓']
print(fruits[1])        # 取出列表中的'西瓜'

执行结果如下

西瓜

《5分钟带你了解Python中的容器型数据类型–列表1》也讲过,列表中的元素是有下标的,如下这样
在这里插入图片描述

那么,同理,我们想取fruits中的其他元素,更改一下下标就可以,这里不再举例

值得注意的是,不但可以对列表进行正向索引,还可以对它进行逆向索引,也就是说,列表中的元素不但在正向上有下标(从前到后的顺序,从0开始编号),在逆方向上仍然是有下标的,用刚刚的fruits列表举例,它的下标是这样的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NMAGyx9f-1627315365972)(C:\Users\86158\AppData\Roaming\Typora\typora-user-images\image-20210726223942680.png)]

于是,如果我们这样取

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓']
print(fruits[-5])        # 取出列表中的'西瓜'

同样可以得到列表里面的’西瓜’

索引只是在列表中找出相应的元素,而不会对列表本身作任何修改,但是在对索引的元素值进行修改时,列表中的对应元素值也被修改

如:

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓']
print(fruits[-5])        # 取出列表中的'西瓜'
print(fruits)

输出:

['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓']      # 原并没有改变列表

而如果

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓','杨梅']   # 定义一个列表\
fruits[0] = '西瓜'     # 将第一个元素改成'西瓜'
print(fruits)

输出:

['西瓜', '西瓜', '梨子', '火龙果', '苹果', '蓝莓', '杨梅']    # 第一个元素已经更改成“西瓜"

掌握了列表的索引,那下面我们再看看什么是列表的切片呢?

  • 列表的切片

从字面上来看,对一个东西切片,那就是将这个物品切成一片儿一片儿的,那么,其实列表的切片和这个意思也是很像的。在一个列表中,根据列表的下标将元素“切”下来列表的一部分生成另一个列表,那么,这个过程就叫做对列表的切片。这里的“切”只是一个形象的说法,而它不像是真的在列表上切,而只是像索引那样,查找到相应的元素,不同的是,切片出来的元素会是一个新的列表,而列表本身不会被修改,而索引出来的元素是一个某种数据类型的单个数据

对一个列表做切片操作,语法是

列表名[开始下标:结束下标:步长]           # 步长在之前讲for循环时range()函数的使用已经讲过
                                     # 取不到结束下标对应的元素,只能取到它的上一个

例如:

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓']   # 定义一个列表
fruits1 = fruits[1:4:1]   # 切片得到的列表复制给一个新列表fruits1,
                            #步长为1,可以省略即fruits1 = fruits[1:4]
print(f"fruits1 = {fruits1}")  
print(f"fruits = {fruits}") 

输出结果

fruits1 = ['西瓜', '梨子', '火龙果']
fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓']

可以知道原本的列表是没有被修改的

如果我们想从第一个元素到最后一个元素进行切片,并且想“跳着”取,就是想取到一个、隔一个再取一个,那么可以这样做:

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓','杨梅']   # 定义一个列表
fruits1 = fruits[::2]             # 从第一个开始可以省略,到最后一个结束也可以省略
print(fruits1)      

输出结果

['香蕉', '梨子', '苹果', '杨梅']

由于是从第一个开始到最后一个(在整个列表中查找,所以可以取到最后一个元素)

在上面,我们知道列表有正向索引,还有逆向索引,那么,切片是不是也有逆向切片呢?没错,是的,同样我们可以采用逆向索引,例如

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓','杨梅']   # 定义一个列表
fruits1 = fruits[-1::-1]             # 从最后一个开始反向查找全部,步长为-1
print(fruits1)

输出结果

['杨梅', '蓝莓', '苹果', '火龙果', '梨子', '西瓜', '香蕉']      # 得到一个反向的列表

其他相关操作自己赶紧试试,比如看看下列操作能得到是什么样的结果

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓','杨梅']   # 定义一个列表
fruits1 = fruits[-2:-6:-2]            
print(fruits1)
#或者
print(fruits[-1::-3] )

不但可以正向下标和反向下标切片,还可以用正向和反向下标混合进行切片(但只能向一个方向进行切片),如:

fruits = ['香蕉', '西瓜', '梨子', '火龙果', '苹果', '蓝莓','杨梅']   # 定义一个列表         
print(fruits[-5:5])

输出结果

['梨子', '火龙果', '苹果']

赶紧自己试试其它的

2.列表的遍历

对于一个列表,如果我们想看一下它里面的所有元素有哪些,那么这个将所有元素输出来的过程就叫列表的遍历。常用用for循环的遍历方法共三种:

例1

nums = [1, 4, 3, 6, 5, 2, 7]
for i in range(len(nums)):  # 可读可写操作
    print(nums[i], end=' ')

输出结果

1 4 3 6 5 2 7 

例2

for num in nums: # 只读操作,不能加序号,实在要加,加上enumerate(枚举)函数,如例3
    print(num, end=' ')

输出结果

1 4 3 6 5 2 7 

例3

for num in enumerate(nums): # 加上enumerate(枚举)函数可得到索引和值
   print(num)

输出结果

(0, 1) (1, 4) (2, 3) (3, 6) (4, 5) (5, 2) (6, 7)

如果对你有帮助,不要帮助点赞、评论、关注加收藏哦!


例3

```python
for num in enumerate(nums): # 加上enumerate(枚举)函数可得到索引和值
   print(num)

输出结果

(0, 1) (1, 4) (2, 3) (3, 6) (4, 5) (5, 2) (6, 7)

如果对你有帮助,不要帮助点赞、评论、关注加收藏哦!

<think>好的,我现在需要帮助用户了解Python中collections模块的用法,特别是其提供的容器数据类型的使用方法。首先,我要回忆一下用户之前的问题和我的回答,确保信息的一致性。用户之前询问了关于calendar模块的使用,现在转向了collections模块,这属于Python标准库中的另一个重要部分。 首先,我需要确定用户的需求。用户明确提到想了解collections模块的容器数据类型,所以需要重点介绍该模块中的各个类,比如namedtuple、deque、Counter、defaultdict、OrderedDict等。同时,用户提供的引用中提到了OrderedDict在实现LRU缓存中的应用,以及collections模块相比内置数据类型的优势,比如顺序保持和高性能,这些都需要在回答中强调。 接下来,我应该参考用户提供的引用内容。引用1提到collections模块提供了额外的高性能数据类型,比如OrderedDict,这补充了内置字典的无序性。引用3详细列出了collections中的几个重要类,并提到需要导入这些类。引用4展示了使用OrderedDict实现LRU缓存的例子。引用2虽然关于array模块,但用户当前的问题不涉及,可以忽略。 接下来,我需要组织回答的结构。通常,用户指南应包括模块概述、核心类详解、实用场景示例、最佳实践和常见问题解答。这样结构清晰,便于用户逐步理解和应用。 模块概述部分需要简要说明collections模块的作用,强调其扩展了内置数据类型,提供了更高效和专用的容器。例如,可以提到namedtuple用于创建有名字段的元组,deque用于高效的双端队列操作,Counter用于计数等。 在核心类详解部分,每个类需要分点说明,包括功能、创建方式、常用方法和示例代码。例如,namedtuple可以举例如何定义一个有名字的元组,并访问其字段;Counter可以展示如何统计元素出现次数。 实用场景示例部分应结合具体案例,如使用defaultdict处理缺失键,用OrderedDict实现LRU缓存,用Counter统计词频等。这些示例能帮助用户理解如何在实际项目中应用这些容器。 最佳实践部分需要给出使用建议,比如何时选择collections中的类而不是内置类,如何提高代码效率和可读性。例如,在需要维护插入顺序时使用OrderedDict,或者处理大量计数时使用Counter。 常见问题解答部分应解答用户可能遇到的疑问,比如线程安全、性能比较、与内置类的区别等。例如,解释deque的线程安全性,或者为什么在某些情况下defaultdict比普通dict更方便。 同时,需要确保回答中正确引用用户提供的引用内容。例如,在讨论OrderedDict时引用[^4]中的LRU缓存实现,在提到高性能数据类型时引用[^1]和[^3]的内容。 另外,用户之前的对话中关于calendar模块的回答结构可以作为参考,保持一致性。比如使用代码示例、分段说明、注意事项等,使内容易于理解和跟随。 需要注意用户可能对某些概念不太熟悉,比如“命名元组”或“双端队列”,需要用简洁的语言解释,并提供直观的例子。例如,解释namedtuple时,可以对比普通元组,说明其通过名称访问字段的优势。 最后,确保回答符合用户的要求:结构清晰、真实可靠,并包含相关问题。例如,在最后生成相关问题,帮助用户进一步探索collections模块的其他功能或高级用法。 总结来说,我需要系统地介绍collections模块中的各个容器,结合示例和实际应用场景,引用用户提供的资料,并保持回答的结构化和易读性。同时,注意使用中文,避免技术术语过于晦涩,确保用户能够轻松理解和应用所学内容。</think>### Python collections模块容器数据类型使用指南 --- #### 一、模块概述 `collections` 模块是 Python 标准库中**增强容器数据类型**的核心模块,提供比内置类更高效的专用容器。其核心价值体现在: - 扩展内置容器的功能(如有序字典、命名元组) - 提供高性能数据结构(如双端队列`deque`) - 简化复杂数据处理逻辑(如计数器`Counter`、默认字典`defaultdict`) [^3] --- #### 二、核心容器详解 ##### 1. `namedtuple`:命名字段的元组 ```python from collections import namedtuple # 定义坐标点类(字段名用空格分隔) Point = namedtuple('Point', ['x', 'y']) p = Point(11, y=22) print(p.x + p.y) # 输出: 33 print(p[0] + p[1]) # 输出: 33 (仍支持索引访问) ``` - **优势**:增强代码可读性,替代索引访问的元组 - **典场景**:数据库查询结果、多维坐标 ##### 2. `deque`:高效双端队列 ```python from collections import deque d = deque([1, 2, 3]) d.appendleft(0) # 左端插入 d.append(4) # 右端插入 print(d) # 输出: deque([0, 1, 2, 3, 4]) d.pop() # 移除右端元素 d.popleft() # 移除左端元素 print(d) # 输出: deque([1, 2, 3]) ``` - **性能**:左右插入/删除时间复杂度 $O(1)$ - **独特功能**:`maxlen`参数限制队列长度(自动丢弃旧数据) ##### 3. `Counter`:元素计数器 ```python from collections import Counter words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'] word_counts = Counter(words) print(word_counts.most_common(2)) # 输出: [('apple', 3), ('banana', 2)] ``` - **核心方法**: - `elements()`:生成所有元素迭代器 - `subtract()`:元素计数减法操作 - `update()`:合并计数器 ##### 4. `defaultdict`:默认值字典 ```python from collections import defaultdict # 自动为不存在的键创建空列表 dd = defaultdict(list) dd['fruits'].append('apple') dd['fruits'].append('banana') print(dd['vegetables']) # 输出: [] (自动创建空列表) ``` - **工厂函数**:支持`int`、`set`、`lambda`表达式等初始化方式 - **对比普通字典**:避免`KeyError`异常,简化代码逻辑 ##### 5. `OrderedDict`:有序字典 ```python from collections import OrderedDict od = OrderedDict() od['a'] = 1 od['b'] = 2 od['c'] = 3 print(list(od.keys())) # 输出: ['a', 'b', 'c'] (保留插入顺序)[^4] # 实现LRU缓存(最近最少使用) class LRUCache(OrderedDict): def __init__(self, capacity): self.capacity = capacity def get(self, key): if key not in self: return -1 self.move_to_end(key) return self[key] def put(self, key, value): if key in self: self.move_to_end(key) self[key] = value if len(self) > self.capacity: self.popitem(last=False) ``` - **特性**:记录键的插入顺序(Python 3.7+ 普通`dict`已支持有序,但此类提供额外方法) - **特殊方法**:`move_to_end()`、`popitem(last=True)` --- #### 三、实用场景示例 ##### 1. 统计文本词频 ```python from collections import Counter import re text = "Python is powerful. Python is easy to learn. Python is open source." words = re.findall(r'\w+', text.lower()) word_counter = Counter(words) print(word_counter.most_common(3)) # 输出: [('python', 3), ('is', 3), ('powerful', 1)] ``` ##### 2. 高效实现滑动窗口 ```python from collections import deque def sliding_window_max(nums, k): q = deque() result = [] for i, num in enumerate(nums): while q and nums[q[-1]] <= num: q.pop() q.append(i) if q[0] == i - k: q.popleft() if i >= k - 1: result.append(nums[q[0]]) return result print(sliding_window_max([1,3,-1,-3,5,3,6,7], 3)) # 输出: [3,3,5,5,6,7] ``` ##### 3. 多层嵌套字典自动创建 ```python from collections import defaultdict def nested_defaultdict(): return defaultdict(nested_defaultdict) data = nested_defaultdict() data['user']['profile']['name'] = 'Alice' print(data['user']['profile']['age']) # 自动创建空字典,无KeyError ``` --- #### 四、最佳实践建议 1. **类选择指南**: - 需要**快速插入/删除** → `deque` - 处理**缺失键** → `defaultdict` - **元素计数** → `Counter` - 需要**字段名称**的元组 → `namedtuple` 2. **内存优化技巧**: - 使用`__slots__`优化`namedtuple`内存占用 ```python class Point(namedtuple('Point', ['x', 'y'])): __slots__ = () ``` 3. **线程安全注意**: - `deque`的`append()`/`popleft()`是**原子操作**,适合多线程生产者-消费者模式 --- #### 五、常见问题解答 1. **`OrderedDict`与普通字典的区别?** - Python 3.7+ 普通字典已记录插入顺序,但`OrderedDict`提供: - 顺序比较功能(`od1 == od2`会检查顺序) - `move_to_end()`等顺序操作方法 - 更高效的反向迭代(通过`reversed()`) 2. **`defaultdict`的性能损耗?** - 与普通字典相比几乎无额外开销,工厂函数在C语言层实现 3. **何时使用`ChainMap`?** - 合并多个字典时优先查找效率高,适合配置层级管理: ```python from collections import ChainMap defaults = {'color': 'red', 'size': 'M'} user_settings = {'size': 'L'} combined = ChainMap(user_settings, defaults) print(combined['color']) # 输出: red ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Python和数据分析

钟意作者

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

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

打赏作者

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

抵扣说明:

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

余额充值