1

この解決策を解決するには 1001 通りの方法があることを認識しています。最も Pythonic なアプローチと思われる方法を理解するようコミュニティに求めています。

次の形式の辞書のリストがあるとします。

colours = [{"color": "green", "owner": "Mark"},
           {"color": "blue", "owner": "Luke"},
           {"color": "red", "owner": "John"}]

リストは辞書の辞書でなければならないという明らかな事実を見落として、辞書のキーのユーザー入力を指定して、リストから単一の辞書を取得したいと考えていますcolorが、色が一致しない場合はデフォルト値を使用します (できますこの例では「緑」と言います)。

そのため、私は関数を探しています:

def get_with_default(colour, colours, default):

色のリストが返されると、次のようになります。

>>> get_with_default("blue", colours, "green") # Valid dictionary
{"color": "blue", "owner": "Luke"}
>>> get_with_default("black", colours, "green") # Colour doesn't exist
{"color": "green", "owner": "Mark"}

更新(Martijnに感謝)、デフォルト値はハードコードされ、リストにあることがわかっていますがその辞書の他のキー/値のペアは不明/動的です(したがって、「緑」が辞書のキーであることはわかっています、しかし、この単純化されたケースでは、誰が緑を「所有」しているのかわかりません

4

3 に答える 3

4

next()まさにそれを達成するための最もpythonicな関数です:

def get_with_default(colour, colours, default):
    search = (d for d in colours if d['color'] in (colour, default))
    match_or_default = next(search)
    if match_or_default['color'] != default or default == colour:
        return match_or_default
    return next(search, match_or_default)

next()結果が生成されるまで最初の引数をループし、それを返します。最初の引数が使い尽くさStopIterationれた場合、2 番目の引数が指定されていない限り、代わりに が発生します。デフォルトの場合、例外が発生する代わりにその値が返されます。

検索を具現化するジェネレータ式を指定することで、coloursリストを効率的にスキャンして最初の一致を見つけます。それがデフォルトであることが判明した場合は、他の一致が見つかるか、リストの最後に到達するまでスキャンを続けます。

デモ:

>>> get_with_default("blue", colours, "green")
{'color': 'blue', 'owner': 'Luke'}
>>> get_with_default("black", colours, "green")
{'color': 'green', 'owner': 'Mark'}

上記の方法は、入力リストを 1 回スキャンするだけでよく、一致が見つかるとすぐにスキャンが停止するという点で非常に効率的です。

StopIterationデフォルトが存在しない場合、この関数は発生することに注意してください。

>>> get_with_default("black", colours, "purple")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in get_with_default
StopIteration

その場合、最初の呼び出しにデフォルトの戻り値もNone与えることで、代わりに返すことができます。next()

match_or_default = next(search, None)
于 2013-07-22T11:43:58.397 に答える
2

最高ではありませんが、素晴らしく読みやすいです:

def get_with_default(colour, L, default=''):
    temp = None
    for d in L:
        if d['color'] == colour:
            return d
        elif d['color'] == default:
            temp = d
    return temp

テスト時:

>>> get_with_default('blue', colours, 'green')
{'color': 'blue', 'owner': 'Luke'}
>>> get_with_default('black', colours, 'green')
{'color': 'green', 'owner': 'Mark'}
于 2013-07-22T11:54:33.637 に答える