生成器的max是在构建类似列表的对象,还是工作效率更高?

问题描述

假设我有一个目录,其中有文件名,名称'filename_1''filename_2'等,还有一个生成models_paths,我用它来查找最新的数字:>

mypath = 'my/path/filename'
models_paths = Path(mypath).parent.glob(Path(mypath).name + '*')
number_newest = max(int(str(file_path).split('_')[-1]) for file_path in models_paths)

我想知道max是在建立类似列表的数据结构还是在使用类似的算法

number_newest = None
for file_path in models_paths:
    number_current = int(str(file_path).split('_')[-1])
    number_newest = number_current if number_newest is None else max(number_current,number_newest)

换句话说:如果我写的话,我是否会失去处理效率和/或内存效率

mypath = 'my/path/filename'
models_paths = Path(mypath).parent.glob(Path(mypath).name + '*')
models_paths = list(models_paths)
number_newest = max(int(str(file_path).split('_')[-1]) for file_path in models_paths)

解决方法

max不会建立列表。

在此示例中,可以使用自定义对象清楚地说明这一点:

class Thing:
    
    def __init__(self,x):
        self.x = x
        print(f'creating {x}')
        
    def __lt__(self,other):
        return self.x < other.x

    def __del__(self):
        print(f'destroying {self.x}')

    def __str__(self):
        return f'<{self.x}>'
        

print(max(Thing(i) for i in range(5)))

给出:

creating 0
creating 1
destroying 0
creating 2
destroying 1
creating 3
destroying 2
creating 4
destroying 3
<4>
destroying 4

如您所见,一旦确定不再是具有最大值的对象,就会在每个对象上调用__del__方法。如果将它们附加到列表中,则不会是这种情况。

对比:

print(max([Thing(i) for i in range(5)]))

给出:

creating 0
creating 1
creating 2
creating 3
creating 4
destroying 3
destroying 2
destroying 1
destroying 0
<4>
destroying 4

您可以编写一个(效率较低的)等效函数,并证明它具有相同的作用:

def mymax(things):
    empty = True
    for thing in things:
        if empty or (thing > maximum):  # parentheses for clarity only
            maximum = thing
            empty = False
    if empty:
        raise ValueError
    return maximum

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...