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

4.1.6 跳過可迭代對象的開始部分

在實際應用中,我們會有類似跳過可迭代對象的需求。

itertools模塊中有一些函數可以實現這個需求,如itertools.dropwhile()函數。該函數需要傳遞一個函數對象和一個可迭代對象,返回一個迭代器對象,丟棄直到函數返回Flase之前的原有序列中的所有元素,然后返回后面的所有元素。

如讀取一個開始部分是幾行注釋的源文件,代碼如下:


with open('/etc/passwd') as f:
    for line in f:
        print(f'{line}', end='')

如跳過開始部分的注釋行,代碼如下:


from itertools import dropwhile
with open('/etc/passwd') as f:
    for line in dropwhile(lambda line: line.startswith('#'), f):
        print(f'{line}', end='')

如果已經明確知道要跳過的元素的個數,可以使用itertools.islice()函數來代替上述代碼,代碼(iter_skip.py)示例如下:


from itertools import islice
items = ['w', 'o', 'r', 12, 5, 7, 90]
for x in islice(items, 3, None):
    print(x)

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


12
5
7
90

示例中,islice()函數最后的None參數指定了獲取items中從第3個到最后的所有元素,如果None和3的位置對調,意思就是僅僅獲取前3個元素(這與切片的相反操作[3:]和[:3]原理是一樣的)。

dropwhile()和islice()是兩個幫助函數,作用是避免寫出類似如下的冗余代碼:


with open('/etc/passwd') as f:
    # Skip over initial comments
    while True:
        line = next(f, '')
        if not line.startswith('#'):
            break

    # Process remaining lines
    while line:
        # Replace with useful processing
        print(line, end='')
        line = next(f, None)

跳過一個可迭代對象的開始部分與過濾是不同的。如上述代碼的第一個部分可能會這樣重寫:


with open('/etc/passwd') as f:
    lines = (line for line in f if not line.startswith('#'))
    for line in lines:
        print(line, end='')

這樣寫確實可以跳過開始部分的注釋行,但是同樣會跳過文件中其他的注釋行。

注意 這里的方案適用于所有可迭代對象,包括那些事先不能確定大小,如生成器、文件及其他類似的對象。

主站蜘蛛池模板: 乐陵市| 毕节市| 浠水县| 车险| 辰溪县| 天津市| 铅山县| 吐鲁番市| 铅山县| 洪泽县| 台前县| 思茅市| 文安县| 桦甸市| 三门峡市| 武鸣县| 水城县| 铁岭县| 邵东县| 隆安县| 新安县| 鹤峰县| 兴宁市| 无锡市| 察哈| 务川| 康定县| 广水市| 黑龙江省| 深水埗区| 云浮市| 陈巴尔虎旗| 东平县| 房产| 永川市| 呼伦贝尔市| 合川市| 禄劝| 荆门市| 祥云县| 沁阳市|