我试图循环一个目录并加载所有文件。我已经尝试使用一个生成器来加载文件,另一个用于生成批次,并在运行内存时调用第一个生成器。
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()
第二个发电机就是问题所在。理想情况下,我希望两个生成器无限期迭代(第一个应该回到列表的开头)。
谢谢!
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]。