Как я могу сделать этот цикл генератора? - PullRequest
1 голос
/ 19 апреля 2019

Я пытаюсь перебрать каталог и загрузить все файлы. Я попытался использовать один генератор для загрузки файлов, а другой - для генерации пакетов и вызова первого генератора, когда он исчерпывает память.

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()

Во втором генераторе проблема. В идеале я хотел бы, чтобы оба генератора повторялись до бесконечности (первый должен вернуться к началу списка).

Спасибо!

1 Ответ

1 голос
/ 19 апреля 2019

itertools.cycle ()
Один из способов сделать это - использовать itertools.cycle(), который будет по существу хранить результаты генератора, а затем непрерывно зацикливать их снова и снова. Документы

Если вы решите это сделать, вы будете использовать много дополнительной памяти для хранения этих результатов.1014 * В качестве альтернативного метода, вы можете try: и except StopIteration для вашего генератора, чтобы сбросить его обратно в начало.Генераторы всегда вызывают StopIteration, если вы вызываете __next__ на исчерпанном генераторе.


Редактировать: Первоначально я связался с функцией-оболочкой здесь , но код в этом примере фактически не работает.Ниже приведен код, который я протестировал для работы, который, надеюсь, будет полезен.Мой ответ здесь основан на той же концепции.

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, прежде чем вы сможете, по проекту [подробнее] .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...