[英]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...
如何使用相同的模式讀取f1
和f2
等“配對”文件?
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))
似乎代碼是貪婪的, name
和data
的第一個打印給出:
[('n', 'n'), ('a', 'a'), ('m', 'm'), ('e', 'e'), ('1', '1')]
[('3', '0'), ('4', '.')]
在哪里我期望的東西:
[('name1', 'name1')]
[('34', '0.34')]
問題是next
返回字符串並迭代它們(它給你單個字符對)。 你可以只使用文字作為list
和tuple
:
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.