什么是Pythonic方式编写匹配算法

时间:2010-01-11 11:08:04

标签: python

我有这段代码(应该是不言自明的;如果没有,请问):

for tr in completed_taskrevs:
    found = False
    for nr in completion_noterevs:
        if tr.description in nr.body:
            completion_noterevs.remove(nr)
            found = True
            break
    assert found

如何让它变得更加pythonic?

3 个答案:

答案 0 :(得分:8)

试试这个:

for tr in compleded_taskrevs:
    try:
        nrs = (nr for nr in completion_noterevs if tr.description in nr.body)
        completion_noterevs.remove(nrs.next())
    except StopIteration:
        raise ValueError('Some error')

编辑: 德文是对的。断言不是方法,更好地使用标准异常。

答案 1 :(得分:6)

在这里使用assert / AssertionError可能不对,我会说。它对"debugging assertions"很有用,也就是说,确保你的代码是理智的。当你获得无效数据时,它作为一种引发错误的方法没有用,出于很多原因,其中最有趣的可能是断言甚至不能保证执行 - 如果你的代码是用任何优化设置编译的,那么不会。哎呀,即使这是一个调试的东西,我仍然会使用raise--它更具可读性,并且无论何时或为何数据错误都会发生。

所以为了使它更“pythonic”,我会删除断言并用更好的东西替换它。碰巧,存在这样一个更好的东西,它是raise语句。此外,我会用else clause of loops替换笨拙的值set / check,这是在循环耗尽时执行的(或者,对于while循环,当条件变为false时)。因此,如果中断,则不执行else子句。

for tr in completed_taskrevs:
    for nr in completion_noterevs:
        if tr.description in nr.body:
            completion_noterevs.remove(nr)
            break
    else:
        raise ValueError("description not found"); # or whatever exception would be appropriate

除此之外,我可能不会改变任何东西。

答案 2 :(得分:3)

下面的列表生成器可以返回所有有效tr.description in nr.body的项目,但是由于它有很多分支,因此很难简化算法。只要符合你的要求,我就会说你使用的算法。

[nr for tr in completed_taskrevs for nr in completion_noterevs if tr.description in nr.body]