簡體   English   中英

python:zip文件迭代器一起提取下一行

[英]python: zip file iterators together that extract lines by next

有多行數據文件,例如像f1

name1
34
name2
12
name3
331

f2

name1
0.34
name2
0.1
name3
1.0

為了解析單個文件,我使用的成語如下:

with open(f1, "r") as f1: 
    while True:      
        name, data = next(f1), next(f1)
        # Do something with name and data...

如何使用相同的模式讀取f1f2等“配對”文件?

def multi_parser(f1, f2):
    with open(f1, "r") as f1_in, open(f2, "r") as f2_in:    
        while True:
            name, data = list(zip(next(f1_in).rstrip(), next(f2_in).rstrip())), 
                         list(zip(next(f1_in).rstrip(), next(f2_in).rstrip()))

            # Do something with name and data...
            print(list(name))
            print(list(data))

似乎代碼是貪婪的, namedata的第一個打印給出:

[('n', 'n'), ('a', 'a'), ('m', 'm'), ('e', 'e'), ('1', '1')]
[('3', '0'), ('4', '.')]

在哪里我期望的東西:

[('name1', 'name1')]
[('34', '0.34')]

問題是next返回字符串並迭代它們(它給你單個字符對)。 你可以只使用文字作為listtuple

name, data = [(next(f1_in), next(f2_in))], [(next(f1_in), next(f2_in))]

或者如果你想避免所有這些next電話:

f1_in, f2_in = iter(f1_in), iter(f2_in)  # make sure f1_in and f2_in are iterators

for name1, name2, value1, value2 in zip(f1_in, f2_in, f1_in, f2_in):
    name = [(name1, name2)]
    data = [(value1, value2)]

我建議拆分代碼,首先創建一個生成器函數,一次生成兩個元素:

def pairs(file):
    try:
        while True: #broken by StopIteration
            yield next(file), next(file)
    except StopIteration:
        return

這種迭代單個文件的方法可以使用for循環:

for name, data in pairs(f1):
    print(name, data)

然后在同時迭代兩個文件,您可以使用zip輕松完成:

for (name1, data1),(name2,data2) in zip(pairs(f1),pairs(f2)):
    print(name1, data1)
    print(name2,data2)

在我看來,我對pairs定義與:

return zip(file, file)

所以你在技術上可以做你想要的迭代:

for (name1, data1), (name2, data2) in zip(zip(f1,f1),zip(f2,f2)):
    print(name1, data1)
    print(name2, data2)

但我不建議在沒有定義pairs函數的情況下(即使它只是一次返​​回)並且很好地評論它。

問題出現了,因為你將兩個字符串傳遞給zip ,即文件的各行。 zip然后在這些字符串的字符對上返回一個迭代器:

list(zip("asdf", "ghjk"))

[('a', 'g'), ('s', 'h'), ('d', 'j'), ('f', 'k')]

如果你想要一個完整的元組元組,你可以這樣做:

name, data = ([(next(f1_in).rstrip(), next(f2_in).rstrip())], 
              [(next(f1_in).rstrip(), next(f2_in).rstrip())])
def my_iter(f1, f2):
    while True:
        yield [next(f1).strip(), next(f2).strip()], [next(f1).strip(), next(f2).strip()]


with open('f1', 'r') as f1, open('f2', 'r') as f2:
    for name, data in my_iter(f1, f2):
        print(name)
        print(data)

你可以得到如下結果:

['name1', 'name1']
['34', '0.34']
['name2', 'name2']
['12', '0.1']
['name3', 'name3']
['331', '1.0']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM