我正在尝试遍历目录并加载所有文件。我试过使用一个生成器加载文件,使用另一个生成器生成批处理,并在内存不足时调用第一个生成器。
def file_gen(b):
# iterate over my directory and load two audio file at a time
for n in range(len(b)):
path_ = os.path.join(os.path.join(path,'Mixtures'), 'Dev')
os.chdir(os.path.join(path_,b[n]))
y, _ = librosa.load('mixture.wav', sr=rate)
path_vox = os.path.join(os.path.join(path,'Sources'), 'Dev')
os.chdir(os.path.join(path_vox,b[n]))
x, _ = librosa.load('vocals.wav', sr=rate)
yield y, x
list_titles = os.listdir(os.path.join(os.path.join(path,'Mixtures'),'Dev'))
gen_file = file_gen(list_titles)
# second generator
def memory_test():
memory = 0
if memory == 0:
a, b = next(gen_file)
a, _ = mag_phase(spectrogram(a))
b, _ = mag_phase(spectrogram(b))
# calculate how many batches I can generate from the file
memory = a.shape[1]/(n_frames*(time_len-overlap) + time_len)
for n in range(memory):
yield memory
memory = memory -1
test = memory_test()
问题所在的是第二个生成器。理想情况下,我希望两个生成器都无限期地进行迭代(第一个生成器应返回到列表的开头)。
谢谢!
答案 0 :(得分:1)
itertools.cycle()
一种执行此操作的方法是使用itertools.cycle()
,它实际上将存储生成器的结果,然后不断地不断循环它们。 docs
如果您选择这样做,则会消耗大量额外的内存来存储这些结果。
StopIteration除外
作为一种替代方法,您可以try:
和except StopIteration
生成发电机,以将其重置为开始。如果您在用尽的生成器上调用__next__
,则生成器始终会引发StopIteration。
编辑:我最初链接到包装函数here,但该示例中的代码实际上不起作用。以下是经过测试可以正常工作的代码,希望对您有所帮助。我的回答是基于相同的概念。
def Primes(max): # primary generator
number = 1
while number < max:
number += 1
if check_prime(number):
yield number
primes = Primes(100)
def primer(): # this acts as a loop and resets your generator
global primes
try:
ok = next(primes)
return ok
except StopIteration:
primes = Primes(100)
ok = next(primes)
return ok
while True: # this is the actual loop continuing forever
primer()
您会注意到,我们无法隐式引用我们自己的函数以进行自我重置,并且我们也无法使用标准的for loop
,因为它会在您可以使用之前先捕获StopIteration
,根据设计[more info]。