1

我已经实现了这个算法:

def get_hot_pages(self, radius = 2):
    if self.page == None or self.max_pages == None: return []
    hot_pages = []
    for page in xrange(self.page - radius, self.page + radius + 1):
        if page < 0 or page >= self.max_pages : continue
        hot_pages.append(page)
    return hot_pages

但有些事情告诉我这可以更好地实施。有没有更蟒蛇的方式来做到这一点?

4

3 回答 3

6

通常的“技巧”是使用max()andmin()来设置最小和最大页码:

def get_hot_pages(self, radius = 2):
    if self.page is None or self.max_pages is None: return []
    return range(max(self.page-radius, 0), min(self.page+radius+1, self.max_pages))

这种方法的主要优点是:

  • 了解此标准程序的人会立即理解代码的作用(只需阅读一行)。无需阅读整个循环块(其中包含过滤器测试)即可了解某些页面可能超出范围。
  • 这是有效的:循环内没有测试,每次迭代都运行并过滤掉不正确的页码。关注效率通常是件好事(即使在这里无关紧要,但在其他情况下可能很重要):解决方案经常会同时简单、易读且非常有效(即,寻找效率)实际上可以使代码更清晰,因为它迫使人们隔离手头问题的本质)。
于 2013-01-08T11:31:38.853 回答
1

首先,一个非常简单的改进是不生成列表,而是使其成为生成器,这使得函数变得懒惰(并且更易于阅读):

def get_hot_pages(self, radius=2):
    if self.page is None or self.max_pages is None: 
        return
    for page in xrange(self.page - radius, self.page + radius + 1):
        if 0 <= page < self.max_pages: 
            yield page

我们还可以反转循环中的逻辑,删除continue,并使用 Python 更好的语法对单个值进行多次比较,以减少检查的大小。这一切都使它更具可读性和效率。

还要注意x == Noneto的变化x is None,这通常被认为更具可读性(这是因为所有实例None都是相同的,所以通过身份检查就可以了)。除了or,我们也可以这样做None in {self.page, self.max_pages}- 尽管只有两个项目,我会说or更清楚。

我还对空格进行了一些更改以符合PEP-8

于 2013-01-08T11:26:40.207 回答
0

你可以这样转:

hot_pages = []
for page in xrange(self.page - radius, self.page + radius + 1):
    if page < 0 or page >= self.max_pages : continue
    hot_pages.append(page)

对此:

hot_pages = filter( lambda k: k >= 0 and k < self.max_pages, xrange( self.page - radius, self.page + radius + 1 ) )

虽然没什么大不了的,而且阅读起来有点困难(至少在我看来)。

于 2013-01-08T11:29:06.220 回答