最大の奇数
ユーザーに10個の整数を入力してから、入力された最大の奇数を出力するように依頼します。奇数が入力されていない場合は、その旨のメッセージを出力してください。
私はPythonでこの問題を解決しようとしてきましたが、奇数の数学的定義が与えられた場合に考えられるすべてのケースをカバーする方法を見つけたと思います。念のため、あなた自身の基準で私のコードが正しいかどうかを確認したいと思います。
counter = 0
odd = []
while counter < 10:
x = int(input("Enter a number: "))
if abs(x)%2 != 0:
odd.append(x)
counter += 1
if len(odd) == 0:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odd))
回答
現在のプログラムでは、いくつかの点を改善できます。
- 名前
odd
をodds
(に変更しlist
ます)。 not odds
代わりに使用しますlen(odds) == 0
(これが優先される理由については、リストが空かどうかを確認するにはどうすればよいですか?を参照してください)。- 削除し
counter
ます。条件でしか使用counter
しないのでwhile
、実際には全体while
をfor _ in range(10)
。に置き換えることができます。 - フォローPEP 8を。たとえば、インデントレベルごとに4つのスペースを使用します。
これらすべての変更を考慮に入れると、次のようになります。
odds = []
for _ in range(10):
x = int(input("Enter a number: "))
if abs(x) % 2 != 0:
odds.append(x)
if not odds:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odds))
しかし、このプログラムの効率を改善することもできます。現在、最大値を選択する前に、すべての奇数を追跡しています。これは、スペースの複雑さがO(N)であることを意味します。次のように最大の奇数を追跡することで、これをO(1)に変更できます。
max_odd = None
for _ in range(10):
x = int(input("Enter a number: "))
if abs(x) % 2 != 0:
max_odd = x if max_odd is None else max(max_odd, x)
if max_odd is None:
print("No odd number was entered")
else:
print("The largest odd number is: ", max_odd)
None
これまでに奇数が入力されていないことを示すために使用することに注意してください。この場合、奇数が入力さmax_odd
れると、x
直接に設定されます。それ以外の場合は、に設定max_odd
しmax(max_odd, x)
ます。
このタイプのプログラムでは、スペースの複雑さが軽減されるため、効率が向上することに気付くことはありません。しかし、これらの削減が可能な場所を認識することを学ぶことで、それが重要なプログラムで同じパターンを見ることができます。
最後に、もう1つできることがあります。数値str
として解析できない(など""
)が誤って入力された場合にプログラムが数値を累積し続けることを許可する場合は、次のようにラップされたtry
/except
を使用できますwhile
。
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
これは次のものを置き換えます。
x = int(input("Enter a number: "))
元のコードで。これにより、ユーザーが入力str
するint
まで、解析可能なaを入力するように求められ続けます。これはすべて、の同じ反復で発生するためfor
、入力する数の数(この場合は10)は減りません。
前のレビューに追加:
x
が整数の場合、Pythonの場合abs(x) % 2
と同等x % 2
です。モジュロ演算子の出力は、%
第2オペランドと同じ符号を持ちます。- メソッド/クラスの外部でコードを実行する場合は、コードをメインガード内に配置することをお勧めします。詳細については、こちらをご覧ください。
Python 3.8では、関数と:=
一緒に代入演算子を使用してコードを短縮できますmax
。
if __name__ == "__main__":
# Number generator
num_gen = (o for _ in range(10) if (o := int(input("Enter a number: "))) % 2 != 0)
max_odd = max(num_gen, default=None)
if max_odd is None:
print("No odd number was entered")
else:
print(f"The largest odd number is: {max_odd}")
int(input("Enter a number: "))
関数にラップすると、読みやすさが向上します。
def read_input() -> int:
return int(input("Enter a number: "))
if __name__ == "__main__":
num_gen = (o for _ in range(10) if (o := read_input()) % 2 != 0)
max_odd = max(num_gen, default=None)
if max_odd is None:
print("No odd number was entered")
else:
print(f"The largest odd number is: {max_odd}")
無効なユーザー入力を処理する別のバリアントは次のとおりです。
def read_input() -> int:
while True:
try:
return int(input("Enter a number: "))
except ValueError:
continue
if __name__ == "__main__":
try:
max_odd = max(o for _ in range(10) if (o := read_input()) % 2 != 0)
print(f"The largest odd number is: {max_odd}")
except ValueError:
# Since read_input() no longer raises ValueError, the except
# statement here only handles the cases where max() gets no inputs
print("No odd number was entered")
Pythonの前にどのプログラミング言語を練習しましたか?
私はこれのためのワンライナーに言及したいと思います:
max(l,key=lambda x:(x%2,x))
あなたがすでにl
何らかの形で入力したと仮定すると、
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
コードはどのように機能しますか?それは、最大探しkey(x)
のためx
にあるl
と、そのような返しますx
。キーはここに戻っタプルことラムダ関数である(1,x)
奇数のためにx
と(0,x)
さえためx
。タプルは左から右に比較されます。たとえば(1,x)>(0,y)
、everyx
とy
。つまり、「l
奇数が常に偶数よりも大きいと仮定して、最大値を教えてください」と言っているだけです。
したがって、すべてのプログラムは次のようになります
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
m=max(l,key=lambda x:(x%2,x))
if m%2:
print('The largest odd number is: %d'%m)
else: #the greatest is even, therefore no odd numbers
print('No odd number was entered')
Pythonのように、短く、素晴らしく、簡単です。
しかし、私int(input())
は、受け入れられた答えからのtry-exceptブロックが有用であり、奇数値のリスト全体を事前に保存しないことに同意します。
私はPythonで関数型プログラミングのパラダイムを示したかっただけです。Pythonに「それをやりたい(最大値など)」と言うだけで、それがあなたに代わって行われるので、どのように行うべきかを説明する必要はありません。
読んでくれてありがとう。
私は受け入れられた答えの最後の提案に基づいて構築しようとします。
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
私は間違いなくこの提案を支持します、それはあなたのプログラムがただクラッシュする代わりに無効な入力を優雅に扱うことを可能にします。
ただし、使いやすさの問題が発生します。文字を数字に入力したばかりのユーザーは、おそらくそれに気づかなかったでしょう。彼らは、意図した番号を入力したと思い、次の番号に進み、最後にすべての番号を入力したと思ったときに混乱しますが、コンピューターはまだ次の番号を要求しています。
彼らにフィードバックを与える方が良い:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
print("Invalid number will be ignored.")
continue
...またはさらに良いことに、タイプミスした番号を印刷して戻します。
while True:
try:
inputString = input("Enter a number: ")
x = int(inputString)
break
except ValueError:
print("Invalid number will be ignored: {}".format(inputString))
continue
また、入力された有効な番号の完全なリストを、奇数だけでなく保持し、結果の前にすべてをユーザーに印刷して、タイプミスを見つける最後の機会を与えることも検討します。結局のところ、彼らは有効であるが意図しない番号をタイプミスした可能性があります。これによりメモリ使用量が増加し、一部の人はそれを過剰通信と見なすことに注意してください。
print("Numbers provided are: {}".format(all_valid_numbers_inputted))
if not odds:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odds))
これを行う場合、次のステップは「オッズ」変数を取り除き、完全なリストから直接最大のオッズを把握することです。
ここで重要な点は、プロセスの各ステップで1つの簡単なことを実行することです。プログラムはそのように構築します。一度に1つの段階的で厳密に定義されたステップです。すべてを混乱させないでください。たとえば、後で必要な変換や計算を行いながら、ユーザーとやり取りするループなどです。
def as_int(s):
try:
return int(s)
except Exception:
return 0
N = 3
MSG = 'Enter number: '
replies = [input(MSG) for _ in range(N)] # Interact.
nums = [as_int(r) for r in replies] # Convert.
odds = [n for n in nums if n % 2] # Compute.
if odds: # Report.
print(max(odds))