Số lẻ lớn nhất
Yêu cầu người dùng nhập 10 số nguyên và sau đó in ra số lẻ lớn nhất đã được nhập. Nếu không có số lẻ nào được nhập, hãy in thông báo có hiệu lực đó.
Tôi đang cố gắng giải quyết vấn đề này với python và tôi nghĩ rằng tôi đã tìm ra một cách bao gồm tất cả các trường hợp có thể đưa ra định nghĩa toán học về một số lẻ. Để chắc chắn, tôi muốn kiểm tra xem mã của tôi có đúng hay không theo tiêu chí của riêng bạn.
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))
Trả lời
Đối với chương trình hiện tại của bạn, chúng tôi có thể cải thiện một số điều:
- Đổi tên
oddthànhodds(vì nó là alist). - Sử dụng
not oddsthay vìlen(odds) == 0(xem Làm cách nào để kiểm tra xem danh sách có trống không? Để biết lý do tại sao danh sách này được ưu tiên). - Xóa
counter. Vì chúng tôi chỉ sử dụngcountertrongwhileđiều kiện, chúng tôi thực sự có thể thay thế toàn bộwhilebằngfor _ in range(10). - Thực hiện theo PEP 8 . Ví dụ: sử dụng 4 dấu cách cho mỗi mức thụt lề.
Bao thanh toán trong tất cả những thay đổi này, chúng tôi nhận được:
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))
Nhưng chúng tôi cũng có thể nâng cao hiệu quả của chương trình này. Ngay bây giờ, chúng tôi theo dõi tất cả các số lẻ, trước khi chọn giá thầu CPC Điều này có nghĩa là độ phức tạp của không gian là O (N). Chúng ta có thể thay đổi giá trị này thành O (1) bằng cách theo dõi số lẻ lớn nhất như sau:
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)
Lưu ý rằng chúng tôi sử dụng Noneđể biểu thị rằng không có số lẻ nào được nhập cho đến nay, trong trường hợp đó khi nhập số lẻ, chúng tôi đặt max_oddthành xtrực tiếp. Nếu không, chúng tôi đặt max_oddthành max(max_odd, x).
Đối với loại chương trình này, bạn sẽ không nhận thấy sự gia tăng hiệu quả do giảm độ phức tạp của không gian. Nhưng học cách nhận biết những nơi có thể cắt giảm được sẽ cho phép bạn nhìn thấy những mẫu tương tự trong các chương trình mà nó quan trọng.
Cuối cùng còn một điều nữa bạn có thể làm. Nếu bạn muốn cho phép chương trình tiếp tục tích lũy các số trong trường hợp strvô tình nhập a mà không thể phân tích cú pháp thành một số (chẳng hạn như ""), chúng ta có thể sử dụng a try/ exceptđược bao bọc trong một whilenhư vậy:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
Điều này sẽ thay thế:
x = int(input("Enter a number: "))
trong mã gốc. Điều này sẽ tiếp tục nhắc người dùng nhập một strcó thể phân tích cú pháp như một intcho đến khi họ thực hiện. Vì tất cả điều này đều xảy ra trong cùng một lần lặp lại for, nên số lượng số mà chúng nhận được để nhập (10 trong trường hợp của chúng tôi) sẽ không bị giảm.
Thêm vào bài đánh giá trước:
- Khi
xlà một số nguyên,abs(x) % 2tương đương vớix % 2trong Python. Đầu ra của toán tử modulo%có cùng dấu với toán hạng thứ hai. - Khi chạy mã bên ngoài một phương thức / lớp, bạn nên đặt mã bên trong một trình bảo vệ chính . Xem ở đây để giải thích thêm.
Trong Python 3.8, mã có thể được rút ngắn bằng cách sử dụng toán tử gán :=cùng với maxhàm.
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}")
Gói int(input("Enter a number: "))thành một hàm cung cấp khả năng đọc tốt hơn:
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}")
Một biến thể khác xử lý thông tin đầu vào của người dùng không hợp lệ như sau:
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")
Tôi có thể hỏi bạn đã thực hành ngôn ngữ lập trình nào trước khi python không?
Tôi muốn đề cập đến một lớp lót cho điều này:
max(l,key=lambda x:(x%2,x))
giả sử bạn đã lnhập bằng cách nào đó, như
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
Mã hoạt động như thế nào? Nó tìm kiếm tối đa key(x)cho xvào lvà trả về như vậy x. Chìa khóa ở đây là hàm lambda trả về tuple (1,x)cho số lẻ xvà (0,x)cho số chẵn x. Các bộ giá trị được so sánh từ trái sang phải, ví dụ: (1,x)>(0,y)cho mọi xvà y. Vì vậy, chúng tôi chỉ nói "cho tôi mức tối đa l, giả sử rằng một số lẻ luôn lớn hơn một số chẵn".
Vì vậy, tất cả chương trình sẽ giống như
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')
Ngắn gọn, đẹp và dễ dàng, như con trăn.
Nhưng tôi đồng ý rằng khối thử ngoại trừ xung quanh int(input())biểu mẫu câu trả lời được chấp nhận là hữu ích, cùng với việc không lưu trữ trước toàn bộ danh sách các giá trị lẻ.
Tôi chỉ muốn chứng minh mô hình của lập trình chức năng trong python, khi bạn chỉ cần nói với python 'Tôi muốn điều đó được thực hiện (ví dụ: giá trị tối đa)' và nó sẽ làm được điều đó cho bạn, bạn không cần giải thích nó phải làm như thế nào.
Cảm ơn vì đã đọc.
Tôi sẽ cố gắng xây dựng dựa trên gợi ý cuối cùng của câu trả lời được chấp nhận.
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
Tôi chắc chắn tán thành đề xuất này, nó cho phép chương trình của bạn xử lý đầu vào không hợp lệ một cách duyên dáng thay vì chỉ gặp sự cố.
Tuy nhiên, nó tạo ra một vấn đề về khả năng sử dụng. Người dùng vừa gõ một chữ cái thành một con số có lẽ đã không nhận thấy điều đó. Họ sẽ nghĩ rằng họ đã nhận được số dự định, tiếp tục với số tiếp theo, và sau đó bối rối ở cuối, khi họ nghĩ rằng họ đã nhập tất cả các số, nhưng máy tính vẫn yêu cầu số tiếp theo.
Tốt hơn nên cung cấp cho họ phản hồi:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
print("Invalid number will be ignored.")
continue
... hoặc thậm chí tốt hơn, hãy in lại số đã đánh máy của họ:
while True:
try:
inputString = input("Enter a number: ")
x = int(inputString)
break
except ValueError:
print("Invalid number will be ignored: {}".format(inputString))
continue
Tôi cũng sẽ cân nhắc giữ danh sách đầy đủ các số hợp lệ đã nhập, không chỉ là số lẻ và in lại tất cả chúng cho người dùng trước khi có kết quả, để cho họ cơ hội cuối cùng để phát hiện lỗi chính tả. Rốt cuộc, họ có thể đã nhập sai một số hợp lệ nhưng không theo ý muốn. Lưu ý rằng điều này sẽ làm tăng mức sử dụng bộ nhớ và một số người sẽ coi nó là giao tiếp quá mức.
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))
Nếu bạn làm điều này, bước tiếp theo sẽ là loại bỏ biến "tỷ lệ cược" và tìm ra số lẻ lớn nhất trực tiếp từ danh sách đầy đủ.
Điểm mấu chốt ở đây: mỗi bước trong quy trình chỉ thực hiện một điều đơn giản. Bạn xây dựng các chương trình theo cách đó - từng bước gia tăng, được xác định chặt chẽ tại một thời điểm. Đừng trộn mọi thứ trong một mớ bòng bong - ví dụ như một vòng lặp nơi chúng ta tương tác với người dùng đồng thời thực hiện chuyển đổi và tính toán cần thiết sau này.
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))