4

免責事項:すべてのPythonマスターとファンの皆さん、こんにちは。皆さんの思いやりのあるサポートと、私を大いに助けてくれた親愛なるアドバイスに感謝したいと思います。私はPythonの初心者であり、ベストプラクティスの重要性を念頭に置きながら、学び、進歩しようとしています。ここで私がここで学んだことが1つあるかのように、型チェックを回避するための迅速な方法を探している質問があります。それは良いことではなく、別の方法が必要です。

サイトマップを表すデータオブジェクトを作成しています。これをメモリに保存して、DBにクエリを実行する前にURLをすばやくマップできるようにします。

各ノードには2つの要素が必要です。(Webサイトのセクションの)名前とID DB内のID)(通常は4〜8桁ですが、ここでは1桁のみで表されます)。

このノードに(ページ上に)子がある場合、名前、ID 、および子を表す別の辞書があります。

パフォーマンス、反復の容易さ、およびメモリの理由から、次のものを使用することに しました。過去に試したのは、[name、id、[name、id、..]]、辞書のみで、これはそうではないと思います。間違った方法。

sitemap = {'section_one': 0,
           'section_two': [1, {'c_sect_2_1': 10,
                         'c_sect_2_2': [11, {'c_sect_2_2_1': 110,
                                           'c_sect_2_2_2': 111,
                                           'c_sect_2_2_3': 112}],
                          'c_sect_2_3': 12,
                          'c_sect_2_4': 13}],
           'section_three': 2,
           'section_four': 3,
           'section_five': 4}

リストを変更する必要があるかもしれないので(したがってタプルはありません )、辞書(ハッシュ可能)を使用していて、セクションが含まれているかどうかを簡単に確認できるため、リストを選択しました。

このデータセットを使用して、以下の関数を使用して、URL(たとえば、/ section_two / c_sect_2_2 / c_sect_2_2_3)をマップし、それが存在するかどうかを確認して、DBからデータをフェッチします。このための私の機能:

def map_url(url): #url here is a list e.g. ['section_two', 'c_sect_2_2', 'c_sect_2_2_3']
    sm = sitemap
    for e in url:
        if e in sm:
            if isinstance(sm[e], int):
                return sm[e] #e = where it stops matching due to no children
            sm = sm[e][1] #if not INT it's a list. list[1] has another dict to go-through
    return False #the URL could not be matched-mapped

私の質問は次のとおりです。

  1. 辞書の項目の値が整数であるかどうかをチェックして子があるかどうかを確認する代わりに、どうすればよいですか?私に何ができる?
  2. このすべてに代わるものは何でしょうか?(データ構造の構築方法および/またはデータ構造の反復)

私のウェブサイトにはネストされたセクションがたくさんある可能性があり、DBが存在するかどうかを確認するためだけに、DBに何度もクエリを実行したくないので、このURLマッピングの方法が必要です。

最後に、貴重な時間をありがとうございました。

4

3 に答える 3

6

ディクショナリ内の項目の値が整数であるかどうかをチェックして、子があるかどうかを確認する代わりに、どうすればよいですか? 私に何ができる?

問題は、子のあるセクションと子のないセクションで異なる表現を使用しているようです。子のないセクションは、実際には子の空のリストを持つセクションであるべきです:

sitemap = {'section_one': [0, {}],
           'section_two': [1, {'c_sect_2_1': [10, {}],
                               'c_sect_2_2': [11, {'c_sect_2_2_1': [110, {}],
                                                   'c_sect_2_2_2': [111, {}],
                                                   'c_sect_2_2_3': [112, {}]}],
                               'c_sect_2_3': [12, {}],
                               'c_sect_2_4': [13, {}]}],
           'section_three': [2, {}],
           'section_four': [3, {}],
           'section_five': [4, {}]}

これで、コードが少し単純になるはずです。

このすべてに代わるものは何ですか?(データ構造の構築方法および/またはそれを介した反復)

プログラムの開始時にサイトマップをフラットな辞書に変換すると、次のようになります。

flat_sitemap = { 
    'section_one': 0,
    'section_two': 1,
    'section_two/c_sect_2_1': 10,
       # ...
    'section_two/c_sect_2_2/c_sect_2_2_1': 110
       # ...
    }

O(1)そうすれば、より高いスペース使用量を犠牲にして、クエリが予想される時間内に機能します。

元の構造を別の方法で処理するには、再帰を使用できます。再帰的な方法でツリーのような構造でアルゴリズムを定式化する方が簡単だと思うことがよくありますが、それはあなたの考え方に少し依存します. 例を次に示します (sitemap最初のサンプルに示されている形式を想定しています)。

def map_url(url, sm=[None, sitemap]):
    if not url: return sm[0]
    if url[0] not in sm[1]: return False
    return map_url(url[1:], sm[1][url[0]])

print map_url(['section_two', 'c_sect_2_2', 'c_sect_2_2_3']) # => 112
print map_url(['section_two', 'c_sect_2_2'])                 # => 10
print map_url(['section_two', 'notexisting'])                # => False
print map_url([])                                            # => None

ご覧のとおり、これにより、空の URL を渡す特別なケースが明確になります。その特定のケースで何が起こるべきかを確実に考える必要があります。

関数の 2 行目をそのままにしておくこともできます。その場合KeyError、URL が一致しない場合は a がスローされます (これも賢明なようです)。

于 2012-08-19T14:57:19.180 に答える
4

より一貫したアプローチは、id と dict の組み合わせを常に使用することですが、子がない場合は空の dict を使用します。

sitemap = {'section_one': [0, {}],
           'section_two': [1, {'c_sect_2_1': [10,{}],
                         'c_sect_2_2': [11, {'c_sect_2_2_1': [110,{}],
                                           'c_sect_2_2_2': [111,{}],
                                           'c_sect_2_2_3': [112,{}]}],
                          'c_sect_2_3': [12,{}],
                          'c_sect_2_4': [0,{}]}],
           'section_three':[2,{}],
           'section_four': [3,{}],
           'section_five': [4,{}]}

そうすれば、残りの URL 部分が子辞書にあるかどうかをいつでも確認できます。

于 2012-08-19T14:57:19.773 に答える
0

For your first question: a pythonic way isn't to check the type, but to try and catch an exception:

sm = sitemap
for e in url:
    if e in sm:
        try:
            sm = sm[e][1]
        except TypeError:
            return sm[e]
return False 

Here, if sm[e] is an integer, it cannot be indexed and a TypeError exception is raised: you can then return your item. If sm[e] can be indexed, you update your sm. Should indexing fail (for example, because there's only one element), another exception would be raised that you could also catch.

于 2012-08-19T14:52:57.177 に答える