我正在尝试在以下两个定义中决定我的生成器。哪个更好?哪一个更像Python?有没有办法减轻每一种方法的缺点?在
def myGenerator1(howMany):
result = [0,0,0]
yield result
for i in range(howMany)
modifyListInPlace(result)
yield result
for val in myGenerator1(1000):
useValThenForgetIt(val)
def myGenerator2(howMany):
result = (0,0,0)
yield result
for i in range(howMany)
result = createNewUpdatedTuple(result)
yield result
for val in myGenerator2(1000):
useValThenForgetIt(val)
第一个修改生成器返回的值,可能会扰乱调用我还没有预见到的代码。在本例中,第二个产生1000个元组的垃圾,如果我增加“howmount”(我可能会这样做),则会产生更多的垃圾。在
我举的循环只是我当前使用的生成器。我不认为我会保存它产生的值,但它有点实用性,可能在其他地方有用。在
以标准库为指南,itertools模块中的组合函数都会返回元组,尽管底层算法是一个突变就地算法。例如,查看itertools.permutations的代码。在
这种设计(返回元组而不是列表)已经被证明是健壮的。根据调用方返回的值,我很难找到这个值。在
还有一个想法。我不会太担心为未使用的结果“创建价值数千元组的垃圾”。Python的元组实现非常善于重用以前处理过的元组(通过使用freelists数组,它可以从以前使用的元组中创建一个新的元组,而无需调用内存分配器)。因此,元组版本只是列表版本的一个性能,甚至更好一些。在
第一种方法可以返回一个对象,然后在返回对象之后再对其进行明显的修改,这对我来说是一种巨大的代码气味,不管你使用的是什么语言(也就是说,这不是“pythonic”的问题)。另外,为什么你想要一个函数,一次又一次地为同一个值生成迭代器,在不同的结果之间进行修改?对我来说似乎很不了解。在
如果使用这些值,
myGenerator2
创建的元组不是垃圾。如果一次只使用一个,它们将永远不会同时存在,而且您的程序几乎肯定会执行许多其他内存分配/释放。与range(howMany)
返回的列表不同,将创建1000个您从未实际使用过的整数(除非您使用Python3,在这种情况下,range
返回生成器而不是列表)。在如果任何调用方可能希望保留对生成器返回的内容的引用(而Python程序员通常希望,当给定一个生成器时,如果需要多次使用生成器,则可以使用
items = list(generator)
),那么第二种方法要高得多。在相关问题 更多 >
编程相关推荐