18

次のコードで、より効率的/より「Pythonic」なコードはどれですか? try-catch 句または if-else 句を使用していますか?

fname = 'AdobeARM.log'

letters = {}

with open(fname,'r') as f:
    for line in f:
        for c in line:
            try:
                letters[c] += 1
            except KeyError:
                letters[c] = 1

print letters

対。

fname = 'AdobeARM.log'

letters = {}

with open(fname,'r') as f:
    for line in f:
        for c in line:
            if letters.has_key(c):
                letters[c] += 1
            else:
                letters[c] = 1

print letters

私は try catch オプションを使用する傾向がありますが、その理由はわかりません。

4

4 に答える 4

23

使用dict.get():

get(key[, default])

キーkeyが辞書にある場合は値を返し、そうでない場合は値を返しますdefault。が指定されていない場合 default、デフォルトで に設定されるNoneため、このメソッドはKeyError.

つまりd.get('x', c)、 と同等d['x'] if 'x' in d else cです。

例:

In [24]: d = {'a':1, 'b':2}

In [27]: d['d'] = d.get('d', 0) + 1  # 0 is the default value

In [28]: d
Out[28]: {'a': 1, 'b': 2, 'd': 1}

In [29]: d['d'] = d.get('d', 0) + 1

In [30]: d
Out[30]: {'a': 1, 'b': 2, 'd': 2}
于 2012-09-09T20:46:23.353 に答える
17

Python のバージョンによっては、ここで adefaultdictまたは aを使用することをお勧めしCounterます。これが最も適切だからです。

さて、どの選択肢が最もpythonicであるかについては、質問する人によって異なります. 一方では、例外は例外的な状況で発生し、条件として使用されるべきではないため、例外ベースのフロー制御は時々嫌われます。

ただし一方で、条件分岐が実用的ではないために、むしろ try / except を使用したい状況もあります。

最後に、パフォーマンスの観点からは、ほとんどの場合にキーがそこにあると予想するかどうかによって異なります (ifステートメントは少し遅くなりますが、例外が発生すると非常に遅くなります)。パフォーマンスが懸念される場合は、決定する前に、両方の実装でパフォーマンスを測定する必要があります。


全体として、一般的な経験則はデフォルトで条件を使用することですが、例外がより実用的である/より理にかなっている/本当に必要なスピードアップを提供する場合は、例外を使用すると思います。

于 2012-09-09T20:52:47.080 に答える
10

よりPythonicは、ジョブ専用のツールを使用することです:

from collections import Counter

with open(fname, 'r') as f:
    letters = Counter(f.read())

has_keyまた、は推奨されていないことに注意してくださいin

于 2012-09-09T20:52:37.377 に答える
1

このトリックを使用して例外をPythonで処理できるかどうかを確認してください。

adict = {}
default = None
val = adict.get('dogname', default)
# val will be None rather than raise an exception.

参考:https ://wiki.python.org/moin/KeyError

于 2014-04-18T19:14:47.763 に答える