【问题标题】:Return iterator vs Return whole list in Python?在 Python 中返回迭代器与返回整个列表?
【发布时间】:2016-02-13 01:34:43
【问题描述】:

我测试了一些代码以了解哪个有效,返回迭代器并返回整个列表。

该程序是关于读取.txt文件的所有行(非常大)并创建字数统计字典(Python3.4)。

1.返回迭代器

from collections import defaultdict
import time

def create_word_cnt_dict(line_iter):
    doc_vector = defaultdict(int)
    for line in line_iter:
        for word in line.split():
            doc_vector[word] += 1
    return dict(doc_vector)

def read_doc(doc_file):
    with open(doc_file) as f :
        while True:
            line = f.readline()
            if not line:
                break
            yield line

t0 = time.time()
line_iter = read_doc("./doc1.txt")
doc_vector = create_word_cnt_dict(line_iter)
t1 = time.time()
print(t1-t0)

需要,3.765739917755127

2.返回整个列表

from collections import defaultdict
import time

def create_word_cnt_dict(line_list):
    doc_vector = defaultdict(int)
    for line in line_list:
        for word in line.split():
            doc_vector[word] += 1
    return dict(doc_vector)

def read_doc1(doc_file):
    with open(doc_file) as f :
        lines = f.readlines()
        return lines

t0 = time.time()
lines = read_doc1("./doc1.txt")
doc_vector = create_word_cnt_dict(lines)
t1 = time.time()
print(t1-t0)

需要,3.6890149116516113

如您所见,返回整个列表要快得多。

但是在内存使用方面,返回迭代器比返回整个列表更有效。

在书Effective Python 中,它建议返回迭代器以提高内存使用效率。但我认为现在时间复杂度比空间复杂度更重要,因为今天的计算机有足够的内存。

请给我一些建议。

【问题讨论】:

  • 取决于你有多少内存。如果您正在使用带有 1M 加行的列表/文件,则迭代器是要走的路。对于普通的家庭编码,我通常只吸收整个文件。
  • 请记住,对于这段代码,使用Counter 对象可能更有意义。
  • 这里没有具体问题,只是请求讨论。
  • @Kupiakos 感谢您的建议:)

标签: python performance time-complexity space-complexity


【解决方案1】:

在这种情况下,我认为您对“更快”的解释与我的不同。 . .时间差异大约为百分之几,这不是很大(用户可能不会注意到,除非您的程序运行 小时,然后差异微不足道。)

再加上迭代器为您提供了更大的灵活性这一事实。如果您想在处理某个行时停止读取行怎么办?在这种情况下,迭代器的速度可能会快 2 倍或更多,因为您已经获得了“短路”的能力。

出于短路和记忆的原因,我更喜欢这里的生成器功能。

还请注意,您的时间安排可能会因您正在阅读文件而有所偏差。 readlines 可能会更有效,因为 python 可以读取比通常更大的文件块,这意味着对操作系统的调用更少。许多其他应用程序不会有这种微妙之处...

【讨论】:

  • 谢谢,但在 readlines 的情况下,如何将每一行转换为小写?我是否已经把每一行都翻遍了?
【解决方案2】:

视情况而定。

如果我们谈论的是相对少量的数据,那么时间复杂度也不会有所不同。

想想海量数据,我不是在谈论GbsTBs,像谷歌和Facebook 这样的大公司每天需要处理的更大的数据集,你认为space complexity 不会算作time complexity吗?

空间我们显然不是在谈论存储内存,而是RAM

所以您的问题非常广泛,它取决于应用程序、您要使用的数据量和您的要求。对于相对较小的数据集,我认为时间复杂度和空间复杂度都不会很大。

【讨论】:

    【解决方案3】:

    性能差异其实非常小。

    鉴于此,优秀的程序员会选择生成器版本,因为它很健壮。

    如果你吞下整个文件,你就是在设置一个陷阱。在未来的某个时候,有人(也许是你)会尝试传入 1GB 或 10GB,他们会被搞砸,到处跑来骂去“为什么??????”

    【讨论】:

      猜你喜欢
      • 2015-09-23
      • 1970-01-01
      • 2018-02-05
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 2013-12-22
      • 1970-01-01
      相关资源
      最近更新 更多