迭代器和生成器, 数据结构

迭代器和生成器, 数据结构

Yiuhang Chan

推导式

在 Python 中,推导式(Comprehensions)提供了一种简洁且高效的方式来创建和操作数据集合。推导式可以应用于列表(list)、字典(dict)、集合(set)以及元组(tuple,仅在 Python 3.8 及以上版本中以生成器表达式的形式支持)。通过使用推导式,可以从一个已存在的数据序列生成一个新的数据序列,同时还可以在过程中对数据进行过滤和转换。

列表推导式

列表推导式是最常用的推导式类型之一,它允许快速生成列表,格式如下:

  • 基本形式

    1
    [表达式 for 变量 in 列表]

    其中,表达式为每个元素的生成公式,for 变量 in 列表部分则是迭代原列表中的每一个元素。

  • 带有条件的形式

    1
    [表达式 for 变量 in 列表 if 条件]

    在这种形式中,if 条件用于筛选符合条件的元素,仅对这些元素应用表达式生成新的列表元素。

在 Python 中,除了列表推导式之外,还支持字典推导式、集合推导式和元组推导式(实际上是生成器表达式)。这些推导式提供了一种高效、简洁的方式来生成新的集合数据类型。以下是对这些推导式的详细介绍和示例。

字典推导式

字典推导式用于创建字典,基本格式如下:

1
{key_expr: value_expr for value in collection}

或者,如果需要根据条件过滤元素:

1
{key_expr: value_expr for value in collection if condition}
  • **key_expr**:键表达式,定义如何生成字典的键。
  • **value_expr**:值表达式,定义如何生成字典的值。
  • **collection**:一个可迭代对象,如列表、元组、集合等。
  • **condition**:一个布尔表达式,用于过滤哪些元素应该被包含在新字典中。

集合推导式

集合推导式用于创建集合,基本格式如下:

1
{expression for item in Sequence}

或者,带有条件的形式:

1
{expression for item in Sequence if conditional}

集合推导式类似于列表推导式,但它生成的是集合,因此结果中自动去除了重复元素。

元组推导式(生成器表达式)

虽然通常称之为元组推导式,但实际上 Python 使用的是生成器表达式来生成元组。生成器表达式返回一个生成器对象,而不是一个立即执行的集合。基本格式如下:

1
(expression for item in Sequence)

或者,带有条件的形式:

1
(expression for item in Sequence if conditional)

生成器表达式使用圆括号(),与列表推导式的中括号[]和字典、集合推导式的大括号{}相区分。

示例

推导式示例

  • 列表推导式示例

    1
    squares = [x**2 for x in range(10)]
  • 字典推导式示例

    1
    square_dict = {x: x**2 for x in range(5)}
  • 集合推导式示例

    1
    square_set = {x**2 for x in [1, -1, 2]}
  • 元组(生成器)推导式示例

    1
    square_gen = (x**2 for x in range(10))

迭代器

python中的迭代器是访问集合的一种方式,每次访问记住遍历的位置。

迭代(Iteration)是指重复执行某个过程的行为,每次都在基于上一次的结果进行操作。在编程中,迭代通常用于遍历数据结构中的元素,例如列表、字典等。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 **next()**。

  • 迭代器通过 iter()将一个可迭代对象变成迭代器,例如list tuple dict set str等,还有就是后面讲到的生成器(generator) 都是可迭代对象
  • 通过next()或者for循环访问迭代的数据

Python中常见的迭代器 有:

  1. 列表迭代器:使用for循环遍历列表。
  2. 字典迭代器:使用for循环遍历字典的键、值或键值对。
  3. 文件迭代器:使用for循环遍历文件中的行。
  4. 生成器:使用yield语句来生成迭代器,可以节省内存空间和计算资源。
  5. itertools模块中的迭代器:包括countcyclerepeatchainzip_longestislicetakewhiledropwhile等。这些迭代器可以实现更加复杂的迭代操作

语法和参数说明

iter函数是一个内置函数,用于创建一个迭代器对象。迭代器是一种特殊的对象,可以通过调用next()函数来逐个访问其中的元素。iter函数接受一个可迭代对象作为参数,并返回一个迭代器对象

iter函数的语法如下所示:

iter(iterable)

其中,iterable是一个可迭代对象,比如列表、元组、字符串等

生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。

然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。

调用一个生成器函数,返回的是一个迭代器对象。

下面是一个简单的示例,展示了生成器函数的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def countdown(n):    
while n > 0:
yield n
n -= 1
# 创建生成器对象
generator = countdown(5)

# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
print(next(generator)) # 输出: 3
# 使用 for 循环迭代生成器
for value in generator:
print(value) # 输出: 2 1

上实例中,countdown 函数是一个生成器函数。它使用 yield 语句逐步产生从 n 到 1 的倒数数字。在每次调用 yield 语句时,函数会返回当前的倒数值,并在下一次调用时从上次暂停的地方继续执行。

通过创建生成器对象并使用 next() 函数或 for 循环迭代生成器,我们可以逐步获取生成器函数产生的值。在这个例子中,我们首先使用 next() 函数获取前三个倒数值,然后通过 for 循环获取剩下的两个倒数值。

生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。

数据结构

在网络上储存了各种形式的数据,当数据量大了的时候,我们对数据进行 增、减、改、查都是建立在数据结构上的。 pthon的数据结构有四种,分别是:列表、字典、元组、集合。这四种代表四种储存数据的方式。

列表(List)

Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能,列表是Python中最基本的数据结构。列表的方法如append(), count(), extend(), index(), insert(), pop(), remove(), reverse(), 和 sort() 提供了丰富的操作,使得列表成为处理序列数据的强大工具。

以下是 Python 中列表的方法:

序号 方法
1 list.append(obj) 在列表末尾添加新的对象
2 list.count(obj) 统计某个元素在列表中出现的次数
3 list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4 list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
5 list.insert(index, obj) 将对象插入列表
6 [list.pop(index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
7 list.remove(obj) 移除列表中某个值的第一个匹配项
8 list.reverse() 反向列表中元素
9 list.sort(cmp=None, key=None, reverse=False) 对原列表进行排序

列表切片

列表切片提供了一种灵活访问列表部分元素的方法。通过指定索引范围,可以轻松获取、修改或删除列表的一部分,这是处理和分析数据时常用的技术。

list=[1,2,3,4,5] 列表是可以切片的,就像我们切面包一样,你想要中间的面包就切中间,要左边就切左边。这个功能有什么用呢,主要作用就是能够让我们对列表中的数值进行索引。

我们要先将列表中的元素进行排序,排序从0开始,如[1,2,3,4,5]分别对应0,1,2,3,4 ,然后通过list=[元素序号:元素序号]进行索引,或者直接填入位置编号。

字典(Dictionary)

建立字典

字典是一种映射类型,它存储键值对,其中键是唯一的。字典的直观性和快速访问特性使它成为存储和操作关联数据的理想选择。创建和访问字典都非常简单高效,是处理复杂数据结构时常用的数据类型。

1
2
3
4
5
myInformation={"myName":"zhangzexiang"} #"myName"就是键,"zhangzexiang"就是值。
print(myInformation)

myInformation={"MyName":"zhangzexiang","Sex":"man","Age":"100"} #包含了姓名、性别、年龄
print(myInformation)

元组(Tuple)

元组是不可变的序列类型,这意味着一旦创建,元组中的元素不能被修改。元组的不可变性使其成为存储不应改变数据的理想选择,例如函数的参数列表。

1
2
3
a=(1,2,3,4,5)
print(a[0])
print(a)

集合(Set)

集合是一个无序的、不包含重复元素的集。它提供了许多标准的集合操作,如并集、交集、差集等。集合的独特性和操作使其成为处理非重复项集时的理想选择。

1
2
3
4
5
a={1,2,3,4,5}
print(a)
a.add(6) #添加
a.discard(1) #删除
print(a)

让我们通过具体的Python代码示例深入理解堆栈和队列的实现及其应用。

堆栈(Stack)

堆栈是一种遵循后进先出(LIFO)原则的数据结构。在Python中,列表的append()方法用于添加元素到列表的末尾,而pop()方法用于移除列表末尾的元素。这两个方法使得列表可以非常方便地被用作堆栈。

示例:使用列表实现堆栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
stack = []

# 向堆栈添加元素
stack.append('A')
stack.append('B')
stack.append('C')
print("Initial stack:", stack)

# 弹出堆栈顶的元素
print("Popped element:", stack.pop())
print("Stack after popping:", stack)

# 再次弹出堆栈顶的元素
print("Popped element:", stack.pop())
print("Stack after popping:", stack)

在这个示例中,我们首先创建了一个空列表stack作为堆栈。然后,我们通过append()方法向堆栈中添加了三个元素。通过调用pop()方法,我们移除了堆栈顶的元素,并打印了每次弹出操作后堆栈的状态。

队列(Queue)

队列是一种遵循先进先出(FIFO)原则的数据结构。尽管可以使用列表来实现队列,但在列表的开始位置插入或删除元素的效率较低。因此,Python的collections模块提供了deque(双端队列),它是为两端都可以高效操作(添加和删除元素)而设计的。

示例:使用collections.deque实现队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from collections import deque

# 创建一个空的双端队列
queue = deque()

# 向队列中添加元素
queue.append('A')
queue.append('B')
queue.append('C')
print("Initial queue:", list(queue))

# 从队列中移除元素
print("Popped element:", queue.popleft())
print("Queue after popping:", list(queue))

# 再次从队列中移除元素
print("Popped element:", queue.popleft())
print("Queue after popping:", list(queue))

在这个示例中,我们首先导入了collections.deque,然后创建了一个名为queue的双端队列。我们通过append()方法在队列末尾添加了元素,并通过popleft()方法从队列的开始位置移除了元素。每次操作后,我们打印了队列的当前状态,以展示队列的先进先出特性。

  • 标题: 迭代器和生成器, 数据结构
  • 作者: Yiuhang Chan
  • 创建于 : 2018-10-18 14:04:36
  • 更新于 : 2024-02-28 18:49:22
  • 链接: https://www.yiuhangblog.com/2018/10/18/20181018迭代器和生成器/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论