2

私は、一連のエントリの最大値と最小値を見つけるという、Python での古典的な学生の問題の 1 つに取り組んでいます。通常、すべての有効なユーザー エントリをリストに入れることでこれを実行したいと考えていますが、代わりに、ユーザーから取得した各エントリを 1 つずつ評価することになっています。(このクラスでは、リストの前にループを扱います。)

私はリストを使用していないので、変数を None と宣言してから、前者のケースは 1 回しか発生しないため、「最大値は None または最大値 < 新規」と評価することに躊躇しています。代わりに、次の解決策にたどり着くまで min() と max() をいじくり回しました。

ここで質問です: これは try/except の有効な使い方ですか? コメントされた代替案よりもpythonicではありませんか?(確かに、最も Pythonic な方法は min([list]) ですが、ここにいます。)

#smallest = None

while True:
    num = raw_input("Enter a number: ")
    if num == "done" : break
    try:
        num = int(num)
    except:
        print 'Invalid input'
        continue

    try:
        smallest = min(num,smallest)
    except NameError:
        smallest = num

#    if num < smallest or smallest is None:
#        smallest = num    

print "Minimum is", smallest
4

2 に答える 2

2

例外を試行して処理することは、一般に Python の基本原則です。<a href="https://docs.python.org/3/glossary.html#term-eafp" rel="nofollow">EAFP、または許可よりも許しを求める方が簡単です。常に適切であるとは限りません。

少なくとも、aNameErrorは一般的にコードの論理エラーであり、例外的な状況を処理するよりも修正する必要があるため、ここにはかなり悪い「コードの匂い」があります。

また、ユーザーが数字をまったく入力しなかった場合にどうなるかを検討してください。を初期化した場合は がsmallest = None出力されますがMinimum is None、これはそれほど不合理ではありません。初期化しないままにしておくと、 unhandled からスタック トレースが出力されますがNameError、これはユーザー フレンドリーではありません。


しかし、簡単な代替手段があります: 有効な入力よりも大きい開始値を選択するだけで、チェックは必要ありません (EAFP または LBYL を介して):smallest = min(num, smallest)常に正しい答えになります。

そのためにどのような値を使用できますか? まあ、無限大は明らかにどの整数よりも大きいので、 から始めることができますfloat('inf')

Minimum is inf(値がない場合よりも良いか悪いかはわかりませんMinimum is Noneが、トレースバックよりは確実に優れています。)


一方、そもそもこの問題を回避するための、よりクリーンな設計があることは注目に値します。コードを分解して整数のストリームを生成するだけで、結果の iterable で好きなことを行うことができます。例えば:

def numbers():
    while True:
        num = raw_input("Enter a number: ")
        if num == "done" : break
        try:
            yield int(num)
        except:
            print 'Invalid input'

smallest = min(numbers())

これには、リストを構築するすべての利点 (呼び出すだけminでよい) があり、欠点はありません (実際にメモリ内にリストを構築する必要はありません)。

iter2 つの引数を使用してraw_input文字列のジェネレーターを生成し、それを 2 つのステップで整数のジェネレーターに変換し、それを に渡すだけで、これをさらに単純化できますmin。でも、初心者の方はこちらの方がわかりやすいと思います。

于 2014-11-05T01:52:17.257 に答える
2

いいえ、それは try/except のかなりばかげた使い方です。

前もって宣言して として定義しNone、次に として更新します。

smallest = num if smallest is None else min(num, smallest)

smallest = []または、として初期化してから、次のように更新することもできます

smallest = [min(smallest + [num])]

それからそれを終わらせる

print("Minimum is {}".format(smallest) if smallest else "No numbers!")
于 2014-11-05T01:44:58.677 に答える