4.10 序列上索引值迭代

2018-02-24 15:26 更新

問題

你想在迭代一個序列的同時跟蹤正在被處理的元素索引。

解決方案

內(nèi)置的 enumerate() 函數(shù)可以很好的解決這個問題:

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

為了按傳統(tǒng)行號輸出(行號從1開始),你可以傳遞一個開始參數(shù):

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

這種情況在你遍歷文件時想在錯誤消息中使用行號定位時候非常有用:

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))

enumerate() 對于跟蹤某些值在列表中出現(xiàn)的位置是很有用的。所以,如果你想將一個文件中出現(xiàn)的單詞映射到它出現(xiàn)的行號上去,可以很容易的利用 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)

如果你處理完文件后打印 word_summary ,會發(fā)現(xiàn)它是一個字典(準(zhǔn)確來講是一個 defaultdict ),對于每個單詞有一個 key ,每個 key 對應(yīng)的值是一個由這個單詞出現(xiàn)的行號組成的列表。如果某個單詞在一行中出現(xiàn)過兩次,那么這個行號也會出現(xiàn)兩次,同時也可以作為文本的一個簡單統(tǒng)計。

討論

當(dāng)你想額外定義一個計數(shù)變量的時候,使用 enumerate() 函數(shù)會更加簡單。你可能會像下面這樣寫代碼:

lineno = 1
for line in f:
    # Process line
    ...
    lineno += 1

但是如果使用 enumerate() 函數(shù)來代替就顯得更加優(yōu)雅了:

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

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

還有一點可能并不很重要,但是也值得注意,有時候當(dāng)你在一個已經(jīng)解壓后的元組序列上使用 enumerate() 函數(shù)時很容易調(diào)入陷阱。你得像下面正確的方式這樣寫:

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):
    ...
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號