【问题标题】:Python for loop efficiencyPython for 循环效率
【发布时间】:2014-10-05 17:42:48
【问题描述】:

我有这个代码块,它可以工作,但执行大约需要 8 秒。我知道这是第二个for 循环,因为循环内部有一个循环。但是,我相信我需要两个循环,因为我需要交叉引用tracks 列表。

有人知道让这个函数执行得更快的方法吗?我似乎看不到另一种写法。

仅供参考:我使用的 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()') 9.776 秒内调用 224565 个函数

   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}

【问题讨论】:

  • 嗯,使用readline(line_num) 比使用for 循环遍历每一行更快。
  • 尝试使用cProfile对其进行分析,看看哪些部分速度较慢。
  • @AHuman 谢谢,但是我如何使用readline(line_num) 来阅读每一行?
  • 这取决于你。但是你可以多使用 5570 行。我将创建一个新的 python 文件,然后将其导入并运行一个包含 5571 行的函数,最后一行返回您的结果。这样你的程序看起来很干净。
  • @sweeneyrod 我将文件名放在函数中,因为我遇到了语法错误。尽管如此,仍然是相同的输出。我用结果编辑了帖子。

标签: python performance loops csv for-loop


【解决方案1】:

这一切只在一个 for 循环中完成:

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.705 秒即可执行。
猜你喜欢
  • 2014-09-02
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 2020-10-10
  • 2015-02-15
  • 1970-01-01
相关资源
最近更新 更多