2014-10-05 6 views
0

У меня есть этот блок кода, который работает, но занимает около 8 секунд. Я знаю, что это второй цикл for, так как внутри цикла есть цикл. Тем не менее, я считаю, что мне нужны оба цикла, потому что мне нужно перекрестно ссылаться на список tracks.Python for loop efficiency

Кто-нибудь знает, как сделать эту функцию быстрее? Кажется, я не вижу другого способа написать это.

FYI: Файл csv, который я использую, имеет 5570 строк, что является еще одной причиной того, что функция принимает «while».

Заранее благодарен!

def load_library(filename) : 
    library = open(filename, 'rb') 
    reader = csv.reader(library, delimiter = '|') 
    tracks = set([]) 
    albums = set([]) 
    albums1 = set([]) 
    #albums1 is the set of albums which have already been added to the albums list. 

    for row in reader : 
     artist, track, album, genre, year = row 
     track = Track(artist, track) 
     track.set_album(album) 
     tracks.add(track) 

    library = open(filename, 'rb') 
    reader = csv.reader(library, delimiter = '|') 

    for row in reader : 
     artist, track, album, genre, year = row 
     a = Album(artist, album) 
     for i in tracks : 
      if str(i.album) == str(a.title) : 
       a.add_track(i.title) 
       if album not in albums1 : 
        albums.add(a) 
     albums1.add(album) 

    return tracks, albums 

После использования c.Profile:

cProfile.run ('load_library()') 224565 вызовы функций в 9.776 секунд

Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.002 0.002 9.776 9.776 <string>:1(<module>) 
    5570 0.001 0.000 0.001 0.000 musiclib.py:18(set_album) 
    11140 0.007 0.000 0.007 0.000 musiclib.py:23(__init__) 
    92784 0.028 0.000 0.037 0.000 musiclib.py:31(add_track) 
    5570 0.004 0.000 0.009 0.000 musiclib.py:6(__init__) 
     1 9.723 9.723 9.775 9.775 musiclib.py:71(load_library) 
     2 0.000 0.000 0.000 0.000 {_csv.reader} 
    16710 0.002 0.000 0.002 0.000 {method 'add' of 'set' objects} 
    92784 0.009 0.000 0.009 0.000 {method 'append' of 'list' objects} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
     2 0.000 0.000 0.000 0.000 {open} 
+0

Ну, это быстрее использовать 'ReadLine (line_num)', то использовать 'for' петлю для прохождения каждой линии. – AHuman

+0

Попробуйте профилировать его с помощью 'cProfile', чтобы увидеть, какие части медленны. – rlms

+0

@Human Спасибо, но как бы я использовал 'readline (line_num)' для чтения каждой строки? –

ответ

5

ли все это только один для цикла:

def load_library(filename) : 
    library = open(filename, 'rb') 
    reader = csv.reader(library, delimiter = '|') 
    tracks = set([]) 
    albums = {} 

    for row in reader : 
     artist, track, album, genre, year = row 
     if album not in albums: 
      a = Album(artist, album) 
      albums[album] = a 
     else: 
      a = albums[album] 
     a.add_track(track) 
     track = Track(artist, track) 
     track.set_album(album) 
     tracks.add(track) 
    return tracks, set(albums.values()) 
+0

Спасибо! Теперь для выполнения требуется всего 0,705 секунды. –