官术网_书友最值得收藏!

4.1.8 序列上索引值迭代

在遍歷序列時,有時需要跟蹤被遍歷元素的索引。對于這種需求,不少開發人員習慣根據序列長度,使用數組下標的方式取得元素索引。

在Python中,不使用數組下標也可以實現在迭代序列的同時跟蹤正在被處理的元素索引。如使用內置的enumerate()函數,代碼(index_iter.py)示例如下:


test_list = ['a', 'b', 'c']
for idx, str_val in enumerate(test_list):
    print(f'index is: {idx}, str value is: {str_val}')

執行py文件,輸出結果如下:


index is: 0, str value is: a
index is: 1, str value is: b
index is: 2, str value is: c

為了按傳統行號輸出(行號從1開始),我們可以傳遞一個開始參數,代碼(index_iter.py)示例如下:


for idx, str_val in enumerate(test_list, 1):
    print(f'index is: {idx}, str value is: {str_val}')

執行py文件,輸出結果如下:


index is: 1, str value is: a
index is: 2, str value is: b
index is: 3, str value is: c

這種方式在錯誤消息中使用行號定位非常有用,示例如下:


def parse_data(file_name):
    with open(file_name, 'rt') as f:
        for lno, line in enumerate(f, 1):
            fields = line.split()
            try:
                count = int(fields[1])
            except ValueError as e:
                print(f'Line {lno}: Parse error: {e}')

enumerate()函數對于跟蹤某些值在列表中出現的位置是很有用的。如果想將一個文件中出現的單詞映射到它出現的行號上,可以利用enumerate()函數實現,代碼如下:


from collections import defaultdict

word_summary = defaultdict(list)
with open('/etc/passwd', 'r') as f:
    line_list = f.readlines()

for idx, line in enumerate(line_list):
    # 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)

處理完文件后打印word_summary,我們會發現它是一個字典(準確來講,word_summary是一個defaultdict)。每個單詞有一個key,每個key對應的值是一個由該單詞出現的行號組成的列表。如果某個單詞在一行中出現兩次,那么其行號也會出現兩次,這可以作為文本的一個簡單統計。

當額外定義一個計數變量的時候,使用enumerate()函數會更加簡單。不使用enumerate()函數,可能會寫出如下代碼:


lno = 1
f = open('/etc/passwd')
for line in f:
    # Process line
    lno += 1

使用enumerate()函數就顯得更加優雅了:


for lno, line in enumerate(f):
    # Process line
    pass

enumerate()函數返回的是一個enumerate對象實例,它是一個迭代器,返回連續的包含一個計數和一個值的元組。元組中的值通過在傳入序列上調用next()函數返回。

注意 有時候,在一個已經解壓的元組序列上使用enumerate()函數很容易掉入陷阱。

enumerate()函數正確與錯誤寫法對比如下(index_iter.py):


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

# Correct!
for n, (x, y) in enumerate(data_list):
    pass

# Error!
for n, x, y in enumerate(data_list):
    pass

主站蜘蛛池模板: 青岛市| 西吉县| 怀柔区| 上虞市| 茶陵县| 金阳县| 罗定市| 延吉市| 东莞市| 治多县| 白水县| 斗六市| 西昌市| 辉县市| 甘孜| 凤翔县| 潼关县| 中西区| 阜新市| 延庆县| 海林市| 巴彦县| 金坛市| 绥宁县| 宝丰县| 尚义县| 明溪县| 镇巴县| 增城市| 佳木斯市| 师宗县| 东丽区| 清涧县| 华蓥市| 蓬溪县| 遵义市| 安国市| 民权县| 当涂县| 衡东县| 克什克腾旗|