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

しかし、これはもっとうまく実装できると何かが教えてくれます。これを行うためのよりPythonicな方法はありますか?

4

3 に答える 3

6

通常の「トリック」は、最小ページ番号と最大ページ番号を設定するためにmax()andを使用することです。min()

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))

このアプローチの主な利点は次のとおりです。

  • この標準的な手順を知っている人は、コードが何をするかをすぐに理解できます (1 行だけを読む必要があります)。一部のページが範囲外になる可能性があることを理解するために、(フィルター テストを含む) ループ ブロック全体を読み取る必要はありません。
  • これは効率的です。反復ごとに実行され、誤ったページ番号を除外するループ内のテストはありません。一般に、効率性に注意を払うことは良いことです (ここでは問題にならない場合でも、他の状況では問題になる場合があります)。解決策が同時に単純で、読みやすく、非常に効率的であることがよくあります (つまり、効率性を求める)。目前の問題の本質を分離することを強制するため、実際にはコードをより読みやすくすることができます)。
于 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 == Noneまた、 toの変更にも注意してくださいx is None。これは、一般にもう少し読みやすいと考えられています (これは、 のすべてのインスタンスNoneが同じであるため機能するため、ID によるチェックで問題ありません)。の代わりにorを使用することもできます。None in {self.page, self.max_pages}ただし、2 つの項目については、 の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 に答える