Weibw's World Weibw's World
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Weibw

一个没有梦想的咸鱼
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《Flask》

  • 《Python Cookbook》第三版

    • 第一章:数据结构与算法

    • 第二章:字符串和文本

    • 第三章:数字日期和时间

    • 第四章:迭代器与生成器

      • 手动遍历迭代器
      • 代理迭代
      • 使用生成器创建新的迭代模式
      • 实现迭代器协议
      • 反向迭代
      • 带有外部状态的生成器函数
      • 迭代器切片
      • 跳过可迭代对象的开始部分
      • 排列组合的迭代
      • 序列上索引值迭代
        • 问题
        • 解决方案
        • 讨论
      • 同时迭代多个序列
      • 不同集合上元素的迭代
      • 创建数据处理管道
      • 展开嵌套的序列
      • 顺序迭代合并后的排序迭代对象
      • 迭代器代替while无限循环
    • 第五章:文件与IO

    • 第六章:数据编码和处理

    • 第七章:函数

    • 第八章:类与对象

    • 第九章:元编程

    • 第十章:模块与包

    • 第十一章:网络与Web编程

    • 第十二章:并发编程

    • 第十三章:脚本编程与系统管理

    • 第十四章:测试、调试和异常

    • 第十五章:C语言扩展

  • Python基础

  • Python
  • 《Python Cookbook》第三版
  • 第四章:迭代器与生成器
weibw
2022-01-06

序列上索引值迭代

# 问题

你想在迭代一个序列的同时跟踪正在被处理的元素索引。

# 解决方案

内置的 enumerate() 函数可以很好的解决这个问题:

>>> my_list = ['a', 'b', 'c']
>>> for idx, val in enumerate(my_list):
...     print(idx, val)
...
0 a
1 b
2 c
1
2
3
4
5
6
7

为了按传统行号输出(行号从1开始),你可以传递一个开始参数:

>>> my_list = ['a', 'b', 'c']
>>> for idx, val in enumerate(my_list, 1):
...     print(idx, val)
...
1 a
2 b
3 c
1
2
3
4
5
6
7

这种情况在你遍历文件时想在错误消息中使用行号定位时候非常有用:

def parse_data(filename):
    with open(filename, 'rt') as f:
        for lineno, line in enumerate(f, 1):
            fields = line.split()
            try:
                count = int(fields[1])
                ...
            except ValueError as e:
                print('Line {}: Parse error: {}'.format(lineno, e))
1
2
3
4
5
6
7
8
9

enumerate() 对于跟踪某些值在列表中出现的位置是很有用的。 所以,如果你想将一个文件中出现的单词映射到它出现的行号上去,可以很容易的利用 enumerate() 来完成:

word_summary = defaultdict(list)

with open('myfile.txt', 'r') as f:
    lines = f.readlines()

for idx, line in enumerate(lines):
    # Create a list of words in current line
    words = [w.strip().lower() for w in line.split()]
    for word in words:
        word_summary[word].append(idx)
1
2
3
4
5
6
7
8
9
10

如果你处理完文件后打印 word_summary ,会发现它是一个字典(准确来讲是一个 defaultdict ), 对于每个单词有一个 key ,每个 key 对应的值是一个由这个单词出现的行号组成的列表。 如果某个单词在一行中出现过两次,那么这个行号也会出现两次, 同时也可以作为文本的一个简单统计。

# 讨论

当你想额外定义一个计数变量的时候,使用 enumerate() 函数会更加简单。你可能会像下面这样写代码:

lineno = 1
for line in f:
    # Process line
    ...
    lineno += 1
1
2
3
4
5

但是如果使用 enumerate() 函数来代替就显得更加优雅了:

for lineno, line in enumerate(f):
    # Process line
    ...
1
2
3

enumerate() 函数返回的是一个 enumerate 对象实例, 它是一个迭代器,返回连续的包含一个计数和一个值的元组, 元组中的值通过在传入序列上调用 next() 返回。

还有一点可能并不很重要,但是也值得注意, 有时候当你在一个已经解压后的元组序列上使用 enumerate() 函数时很容易调入陷阱。 你得像下面正确的方式这样写:

data = [ (1, 2), (3, 4), (5, 6), (7, 8) ]

# Correct!
for n, (x, y) in enumerate(data):
    ...
# Error!
for n, x, y in enumerate(data):
    ...
1
2
3
4
5
6
7
8
编辑 (opens new window)
上次更新: 2023/10/13, 17:39:25
排列组合的迭代
同时迭代多个序列

← 排列组合的迭代 同时迭代多个序列→

最近更新
01
牛客网非技术快速入门SQL练习题
03-08
02
其他日常SQL题
03-07
03
用户与权限管理
03-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 | Weibw | 辽ICP备18015889号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式