Pythonic方法使用自己的元素检查生成器值

时间:2016-05-19 15:57:42

标签: python closures generator

假设我正在逐行读取文件,并希望确保某个字符(例如,表格数据中的分隔符)在每行中显示相同的次数,具体取决于它在第一行中的计数文件。我能想到的最好的方法是使用第二台发电机,但我觉得这并不意味着“应该有一台 - 最好只有一台 - 明显的做法”。使用闭包是否符合这个格言,还是有一些其他显而易见的方式我没有看到?

def check_line(char='|'):
    while True:
        line_count = line.count(char)
        if i == 0:
           correct_count = line_count
        if line_count != correct_count:
           print """Line %d contains %d %s, should have %d""" % (
                 i, line_count, char, correct_count)
        yield None

with open('file.txt', 'rb') as f:
     checker = check_line()
     for i, line in enumerate(f):
         checker.next()
         ### do more things with line 

我试图从我的一般问题中抽象一点,因为我对惯用语实现最好奇,而不是用文件/分隔符解决这个特定问题。

2 个答案:

答案 0 :(得分:2)

我不认为闭包或发电机是必要的。如果只使用简单的函数定义就可以完成,为什么要使用更复杂的东西呢?也许我不能理解你想要的东西,但我要做的是:

def check_lines(_file, delimiter):
    correct_count = _file.readline().count(delimiter)
    for line_number, line in enumerate(_file, start=2): #lets say the first line is line 1, then the first line in this for loop will be line 2
        line_count = line.count(delimiter)
        if line_count != correct_count:
            format_args = (line_number, line_count, delimiter, correct_count)
            print("""Line {} contains {} {}, should have {}""".format(*format_args))

with open(__file__, 'r') as _file:
    check_lines(_file, '(')

我不知道你的功能应该实际做什么。它可以返回或生成您需要的任何信息,而不是打印到stdout。

答案 1 :(得分:2)

要摆脱全局变量,请将读取的行传递到生成器中:

def check_line(char='|'):
    correct_count = None

    while True:
        line = yield None
        line_count = line.count(char)
        if not correct_count:
           correct_count = line_count

        if line_count != correct_count:
           print """Line %d contains %d %s, should have %d""" % (
                 i, line_count, char, correct_count)

with open('file.txt', 'rb') as f:
     checker = check_line()
     for i, line in enumerate(f):
         checker.next(line)

更好的解决方案是完全包装生成器:

def check_line(gen, char='|'):
    correct_count = None
    injected = None

    while True:
        i, line = gen.next(injected)
        line_count = line.count(char)

        if not correct_count:
           correct_count = line_count

        if line_count != correct_count:
           print """Line %d contains %d %s, should have %d""" % (
                 i, line_count, char, correct_count)

        injected = yield i, line

with open('file.txt', 'rb') as f:
     checker = check_line(enumerate(f))
     for i, line in checker:
         print line
相关问题