Python中的平面生成器

Python中的平面生成器,python,generator,list-comprehension,lazy-evaluation,Python,Generator,List Comprehension,Lazy Evaluation,可以在python中执行平面惰性生成吗?例如,我在下面的代码中尝试做的是传入os.walk的结果,并尝试只返回这些结果 def os_walk_transcript(self, walk_results): """Takes the results of os.walk on the data directory and returns a list of absolute paths""" file_check = lambda walk: len(walk[2]) >

可以在python中执行平面惰性生成吗?例如,我在下面的代码中尝试做的是传入os.walk的结果,并尝试只返回这些结果

def os_walk_transcript(self, walk_results):
    """Takes the results of os.walk on the data directory and returns a list of absolute paths"""
    file_check = lambda walk: len(walk[2]) > 0
    srt_prelim = lambda walk: ".srt.sjson" in " ".join(walk[2])
    relevant_results = (entry for entry in walk_results if file_check(entry) and srt_prelim(entry))
    return (self.os_path_tuple_srts(result) for result in relevant_results)

def os_path_tuple_srts(self, os_walk_tuple):
    srt_check = lambda file_name: file_name[-10:] == ".srt.sjson"
    directory, subfolders, file_paths = os_walk_tuple
    return [os.path.join(directory, file_path) for file_path in file_paths if srt_check(file_path)]
对os_walk_转录本的结果进行延迟评估很重要,但我希望能够以一种平坦的方式对其进行评估,而不是当前的嵌套列表评估


例如:当前,当我从生成的生成器请求结果时,我会得到一个完整的
[“1.srt.sjson”,“2.srt.sjson”,“3.srt.sjson”]
,然后如果我再次调用它,我会得到:
[“4.srt.sjson”]
我在一个项目中工作,该项目的数据足够大且不一致,这种行为会导致性能不一致,有时会导致速度比我希望的要慢。有没有办法强迫懒惰的计算变得更懒惰,一次只加载一个对象?

难道你不能这样做一个函数吗

def lazyarray(index):
    return str(index) + ".srt.sjson"
你甚至可以这么做

firstTen = [lazyarray(x) for x in xrange(10)]
完全懒惰,实现起来非常简单。如果你想少一点懒惰(缓存计算),你可以这样做

cache = []
def lazyarray(index):
    if len(cache) <= index:
        cache += ["" for x in xrange(index - len(cache))]
    if cache[index] == "":
        cache[index] = str(index) + ".srt.sjson"
    return cache[index]
就说

lazyarray(5)
它将具有与数组相同的效果

编辑:
您甚至可以重写
\uuuu getitem\uuuu
方法,如图所示,只需基于我上面发布的代码创建一个自定义生成器类。

您可以使用itertools chain.from\u iterable()。文件是

基本上,您可以这样使用它:

import itertools

myList = [[1,2,3],[4,5],[6],[7,8,9]]

itr = itertools.chain.from_iterator(myList)

itr现在将是一个生成器对象,每次调用它时都返回下一个元素。(在本例中,它将与
xrange(10)
)完全相同。

这解决了懒惰部分,但不是平坦部分,这是我实际需要帮助的部分。如果您在上面的代码中注意到,我已经大量使用了惰性计算,但是我需要的是将列表的惰性计算更改为单个元素的惰性计算。我并不想粗鲁,但你似乎没有在发帖前阅读我的问题或查看我的代码。我很抱歉你有这种感觉。我提供了一种回答这篇文章的方法,即使我没有意识到这不是你想要的。我确实阅读了你的代码和问题,我尽了最大努力正确地解释了它。引用一句话,你问“有没有办法强迫它更懒惰,一次只加载一个对象?”这就是我想要回答的问题。我所提供的是一个框架,可以让某些东西在执行时变得非常懒惰。遍历列表很容易,这里的关键是使其成为列表的惰性评估。显然,不是我没能解释这篇文章,就是你需要澄清你的问题。不过,我很高兴有人正确地解释了它。问题不在于对列表的懒惰评估。问题具体地说是对一个已经被延迟评估的列表的延迟评估。非常关键的区别。一个是用括号解决的,另一个需要使用外部模块。你的回答很懒,是的,但不是那么懒。我需要一些递归懒惰的东西,而如果你的懒惰数组中的元素是列表,你就会遇到与我最初提出的完全相同的问题。太棒了!正是我想要的。
import itertools

myList = [[1,2,3],[4,5],[6],[7,8,9]]

itr = itertools.chain.from_iterator(myList)