<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[滑车的世界]]></title><description><![CDATA[一名程序员的日常]]></description><link>https://yuchang.site/</link><image><url>https://yuchang.site/favicon.png</url><title>滑车的世界</title><link>https://yuchang.site/</link></image><generator>Ghost 2.38</generator><lastBuildDate>Fri, 31 Oct 2025 22:57:36 GMT</lastBuildDate><atom:link href="https://yuchang.site/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Python 同时读取多个文件]]></title><description><![CDATA[问题：假设有多个 行数一样  的文件，如何使用 python 同时对这些文件按行进行读取？
解决这个问题需要用到 python 的生成器，实现代码如下：]]></description><link>https://yuchang.site/python-read-multiple-files-simultaneously/</link><guid isPermaLink="false">5ce522bc9352f000014046bf</guid><category><![CDATA[程序语言]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[滑车]]></dc:creator><pubDate>Wed, 22 May 2019 10:53:03 GMT</pubDate><content:encoded><![CDATA[<h2 id="-python-">问题：假设有多个 行数一样  的文件，如何使用 python 同时对这些文件按行进行读取？</h2><h3 id="-">方案一：</h3><p>解决这个问题需要用到 python 的生成器，实现代码如下：</p><!--kg-card-begin: markdown--><pre><code class="language-python">filenames = ['a.txt', 'b.txt', 'c.txt']

def gen_line(fname):
    with open(fname, 'r', encoding='utf-8') as f:
        for line in f:
            yield line.strip()

gens = [gen_line(fname) for fname in filenames]

for a, b, c in zip(*gens):
    print('\t'.join([a, b, c]))

</code></pre>
<!--kg-card-end: markdown--><p></p><!--kg-card-begin: markdown--><p>示例代码中的操作可分为四个步骤：</p>
<ol>
<li>将文件名放入一个 <code>list</code></li>
<li>定义一个按行读取文件的生成器</li>
<li>使用使用列表推导式生成一个生成器的列表（这里也可以换用生成器表达式）</li>
<li>使用 <code>*</code> 语法拆包，然后使用 <code>zip</code> 进行迭代输出</li>
</ol>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p><strong>注意：如果文件的行数不一致，<code>zip</code> 会在迭代完最少行数的文件后退出，且不会有任何异常抛出。如需要保证迭代完所有文件内容，可使用 <code>itertools.zip_longest</code> 替代。</strong></p>
<!--kg-card-end: markdown--><h3 id="--1">方案二：</h3><p>可能会有人觉得上面的解决方案有一点啰嗦，下面提供一个更加精简的解决方案，此方案来自 <a href="https://stackoverflow.com/questions/24108769/how-to-read-and-process-multiple-files-simultaneously-in-python">stackoverflow </a>上面的一篇回答：</p><!--kg-card-begin: markdown--><pre><code class="language-python">from contextlib import ExitStack

filenames = ['a.txt', 'b.txt', 'c.txt']

with ExitStack() as stack:
    files = [stack.enter_context(open(fname)) for fname in filenames]
    for rows in zip(*files):
        print('\t'.join([x.strip() for x in rows]))

</code></pre>
<!--kg-card-end: markdown--><p></p><!--kg-card-begin: markdown--><p>这个方案使用了<code>python 3.3</code> 引入的 <code>contextlib.ExitStack</code> 用于管理文件关闭操作。代码看起来比方案一精简了不少。不过，如果让我来选择的话，我更倾向于使用方案一。原因如下：</p>
<ol>
<li>虽然我非常喜欢精简的代码，行数越少的代码我越喜欢。但是，代码的可读性更为重要。方案二使用了一个并不那么普及的方法，或者说所谓的“高级特性”，代码确实简洁了不少，但却大大降低了代码的可读性，不可取。代码是写给人看的，机器只负责执行它。推荐一篇文章<a href="https://www.infoq.cn/article/gu0HigYOJ-Wf20HayH69">《为什么高级程序员写的代码都是傻瓜式的？》</a>。一句话，<strong>可读性优于代码精简</strong>。</li>
<li>方案二虽然精简，但真正用起来可能并没有方案一方便，看一下 <code>strip</code> 方法的调用位置就能明白。方案一之所以显得啰嗦，是因为专门为打开文件定义了一个生成器。但是，这个生成器可以在其它任何需要打开文件的地方复用，而且用起来非常方便。也许将来某一天，类似的生成器会直接进入 <code>python</code> 的标准库也说不定。</li>
<li>即便是完全使用 <code>python 3</code>，版本的兼容性在很多情况下依然是要需要考虑的。</li>
<li>方案一是我自己想出来的，当然会觉得好。（皮一下，很开心！）</li>
</ol>
<!--kg-card-end: markdown--><p>最后，以上仅为个人观点，方案二其实也挺好的。</p>]]></content:encoded></item></channel></rss>