【问题标题】:Optimize the for loop in python优化python中的for循环
【发布时间】:2017-06-07 09:06:29
【问题描述】:

好的,我目前有以下代码:

n = 0
with open('/home/user/test.filter') as f:

    lines = f.readlines()

    for l in lines:
        if lines[n].startswith('-A vlan_8'):
            if "-o bond1.8" in lines[n]:
                    f = open('vlan8.filter_in', 'a')
                    f.write(l)
            else:
                f = open('vlan8.filter_out', 'a')
                f.write(l)
        if lines[n].startswith('-A vlan_10'):
            if "-o bond1.10" in lines[n]:
                f = open('vlan10.filter_in', 'a')
                f.write(l)
            else:
                f = open('vlan10.filter_out', 'a')
                f.write(l)
        if lines[n].startswith('-A vlan_15'):
            if "-o bond1.15" in lines[n]:
                f = open('vlan15.filter_in', 'a')
                f.write(l)
            else:
                f = open('vlan15.filter_out', 'a')
                f.write(l)

        # [...]

        n = n + 1

我考虑过使用一些累加器或列表来优化它,以使脚本不那么广泛。有什么建议吗?

【问题讨论】:

  • 我认为你的标签在这个例子中有点不正确?
  • 你的意思是优化(更快)还是重构(更少重复)?
  • 首先,不要做== True——这是多余的;如果== 左边的表达式等于True,那么,嗯,这是真的。其次,由于您有多次重复的非常相似的代码,请考虑将其设为函数。第三,在开始时打开你的输出文件一次,而不是每次需要写入时都打开它们 - 你可以保留一个列表,或者更好的是,它们的字典。
  • 您只能在循环之前打开文件(例如 vlan8.filter_in一次,而不是针对您处理的每一行。此外,紧接在for 循环下的所有if 子句(当然第一个除外)都可以转换为elifs。 if lines[n].startswith 不正确,应该是 if lines.startswith,但我没有编辑它们以避免改变问题的语义。

标签: python for-loop optimization iteration


【解决方案1】:

当然可以。维护这些数字的列表:

numList = [8, 10, 15, ...]

现在,您所需要的只是一些字符串格式。

with open('/home/user/test.filter') as f:
    lines = f.readlines()

for i, l in enumerate(lines): # I've used enumerate to eliminate n but really you don't need it
    for num in numList:
        if l.startswith('-A vlan_%d' %num):
            if "-o bond1.%d" %num in l:
                f = open('vlan%d.filter_in' %num, 'a')
            else:
                f = open('vlan%d.filter_out' %num, 'a')

            f.write(l)
            f.close()
            break

【讨论】:

    【解决方案2】:

    我认为你想让代码更简洁,而不是更快。如果是这样,也许这会起作用:

    import re
    
    parameter_re = re.compile(r'^-A vla_(\d+).*')
    
    with open('data.csv') as f:
        lines = f.readlines()
    
    for line in lines:
        # Match required parameter
        match = parameter_re.match(line)
    
        # Skip line if it doesn't match the required parameter
        if not match:
            continue
    
        # Extract number from parameter
        number = int(match.group(1))
    
        # Create output parameter string
        output_str = '-o bond1.%d' % number
    
        # Select correct filename to save the line
        if output_str in line:
            output_filename = 'vlan%d.filter_in' % number
        else:
            output_filename = 'vlan%d.filter_out' % number
    
        # Write the line to the correct file
        with open(output_filename, 'a') as f:
            f.write(line)
    

    如果你想让它更短(我不建议这样做,最好让它可读):

    import re
    
    with open('data.csv') as f:
        lines = f.readlines()
    
    for line in lines:
        match = re.match(r'^-A vla_(\d+).*', line)
        if not match:
            continue
        number = int(match.group(1))
        if '-o bond1.%d' % number in line:
            output_filename = 'vlan%d.filter_in' % number
        else:
            output_filename = 'vlan%d.filter_out' % number
        with open(output_filename, 'a') as f:
            f.write(line)
    

    【讨论】:

      猜你喜欢
      • 2015-04-15
      • 2020-11-07
      • 1970-01-01
      • 2017-02-21
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      相关资源
      最近更新 更多