在Python中返回迭代器还是返回整个列表?

在Python中返回迭代器还是返回整个列表?,python,performance,time-complexity,space-complexity,Python,Performance,Time Complexity,Space Complexity,我测试了一些代码,以了解哪一个是有效的,返回迭代器并返回整个列表。 该程序将读取.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

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

该程序将读取
.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

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

但在内存使用方面,返回迭代器比返回整个列表要有效得多

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


请给我一些建议。

在这种情况下,我认为你对“快得多”的解释与我的不同。时间上的差异大约为百分之几,这不是很明显(除非你的程序运行了几个小时,然后差异就不明显了,否则用户可能不会注意到)

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

出于短路原因和内存原因,我更喜欢这里的发电机功能


还要注意的是,由于您正在读取文件,您的计时可能会有偏差
readlines
可能会更高效,因为python可以读取比通常更大的文件块,这意味着对操作系统的调用更少。许多其他应用程序都不会有这种子分类…

在这种情况下,我认为您对“快得多”的解释与我的不同。时间上的差异大约为百分之几,这不是很明显(除非你的程序运行了几个小时,然后差异就不明显了,否则用户可能不会注意到)

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

出于短路原因和内存原因,我更喜欢这里的发电机功能

还要注意的是,由于您正在读取文件,您的计时可能会有偏差
readlines
可能会更高效,因为python可以读取比通常更大的文件块,这意味着对操作系统的调用更少。许多其他应用程序将不具有此子分类…

视情况而定

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

想想庞大的数据量,我说的不是
Gbs
TBs
,而是像谷歌和Facebook这样的大公司每天需要处理的更大的数据集,你认为
空间复杂性
不算作
时间复杂性

显然,我们谈论的不是存储内存,而是针对
RAM

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

视情况而定

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

想想庞大的数据量,我说的不是
Gbs
TBs
,而是像谷歌和Facebook这样的大公司每天需要处理的更大的数据集,你认为
空间复杂性
不算作
时间复杂性

显然,我们谈论的不是存储内存,而是针对
RAM


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

性能差异实际上很小

有鉴于此,一个好的程序员会选择生成器版本,因为它是健壮的


如果你把整个文件都弄脏了,那就是在设置陷阱。在将来的某个时候,有人(也许你)会试图通过1GB或10GB的测试,他们会被搞砸,然后到处乱跑,咒骂“为什么?”

性能上的差异其实很小

有鉴于此,一个好的程序员会选择生成器版本,因为它是健壮的


如果你把整个文件都弄脏了,那就是在设置陷阱。在将来的某个时候,有人(也许你)会试图通过1GB或10GB,他们会被搞砸,到处乱跑,咒骂“为什么?”

这取决于你到底有多少内存。如果您使用的是带有1M多行的列表/文件,那么迭代器就是最好的选择。对于正常的家庭编码,我通常只需要输入一个完整的文件。请记住,对于这段代码,使用对象可能更有意义。这里没有具体问题,只是一个讨论请求。@Kupiakos谢谢你的建议:)取决于你真正拥有的ram数量。如果您使用的是带有1M多行的列表/文件,那么迭代器就是最好的选择。对于正常的家庭编码,我通常只会插入一个完整的文件。请记住,对于这段代码,使用对象可能更有意义。这里没有具体的问题,只是一个讨论请求。@Kupiakos感谢您的建议:)谢谢,但对于readlines,如何将每一行转换为小写?我是否需要重新检查每一行?谢谢,但如果是readlines,如何将每一行转换为小写?我有什么好看的吗