기능적 접근 방식 또는 " 루프가없는 것처럼 보입니다! ":
from itertools import chain, repeat
prompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies))
print(valid_response)
Enter a number: a
Not a number! Try again: b
Not a number! Try again: 1
1
또는 다른 답변에서와 같이 "잘못된 입력"메시지를 입력 프롬프트와 분리하려면 다음을 수행하십시오.
prompt_msg = "Enter a number: "
bad_input_msg = "Sorry, I didn't understand that."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies))
print(valid_response)
Enter a number: a
Sorry, I didn't understand that.
Enter a number: b
Sorry, I didn't understand that.
Enter a number: 1
1
어떻게 작동합니까?
prompts = chain(["Enter a number: "], repeat("Not a number! Try again: "))
의 조합 itertools.chain
및 itertools.repeat
문자열을 얻을 것입니다 반복자 생성됩니다 "Enter a number: "
한 번, 그리고 "Not a number! Try again: "
시간의 무한한 수를 :
for prompt in prompts:
print(prompt)
Enter a number:
Not a number! Try again:
Not a number! Try again:
Not a number! Try again:
# ... and so on
replies = map(input, prompts)
-여기 에서 이전 단계의 map
모든 prompts
문자열을 input
함수에 적용합니다. 예 :
for reply in replies:
print(reply)
Enter a number: a
a
Not a number! Try again: 1
1
Not a number! Try again: it doesn't care now
it doesn't care now
# and so on...
- 우리는 사용
filter
하고 str.isdigit
숫자 만 포함하는 문자열을 필터링 :
only_digits = filter(str.isdigit, replies)
for reply in only_digits:
print(reply)
Enter a number: a
Not a number! Try again: 1
1
Not a number! Try again: 2
2
Not a number! Try again: b
Not a number! Try again: # and so on...
그리고 우리는 첫 번째 숫자 전용 문자열 만 가져옵니다 next
.
다른 유효성 검사 규칙 :
문자열 메서드 : 물론 str.isalpha
알파벳 문자열 str.isupper
만 가져 오거나 대문자 만 가져 오는 등 다른 문자열 메서드를 사용할 수 있습니다 . 전체 목록 은 문서 를 참조하십시오 .
멤버쉽 테스트 :
여러 가지 방법으로이를 수행 할 수 있습니다. 그중 하나는 __contains__
방법 을 사용 하는 것입니다.
from itertools import chain, repeat
fruits = {'apple', 'orange', 'peach'}
prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
replies = map(input, prompts)
valid_response = next(filter(fruits.__contains__, replies))
print(valid_response)
Enter a fruit: 1
I don't know this one! Try again: foo
I don't know this one! Try again: apple
apple
숫자 비교 :
여기서 사용할 수있는 유용한 비교 방법이 있습니다. 예를 들어 __lt__
( <
)의 경우 :
from itertools import chain, repeat
prompts = chain(["Enter a positive number:"], repeat("I need a positive number! Try again:"))
replies = map(input, prompts)
numeric_strings = filter(str.isnumeric, replies)
numbers = map(float, numeric_strings)
is_positive = (0.).__lt__
valid_response = next(filter(is_positive, numbers))
print(valid_response)
Enter a positive number: a
I need a positive number! Try again: -5
I need a positive number! Try again: 0
I need a positive number! Try again: 5
5.0
또는 dunder 메소드 (dunder = double-underscore)를 사용하지 않으려는 경우 언제든지 자신의 함수를 정의하거나 operator
모듈 의 함수를 사용할 수 있습니다 .
경로 존재 :
여기에서 pathlib
라이브러리와 그 Path.exists
방법을 사용할 수 있습니다 :
from itertools import chain, repeat
from pathlib import Path
prompts = chain(["Enter a path: "], repeat("This path doesn't exist! Try again: "))
replies = map(input, prompts)
paths = map(Path, replies)
valid_response = next(filter(Path.exists, paths))
print(valid_response)
Enter a path: a b c
This path doesn't exist! Try again: 1
This path doesn't exist! Try again: existing_file.txt
existing_file.txt
시도 횟수 제한 :
무한한 횟수로 무언가를 요청하여 사용자를 고문하지 않으려면의 호출에서 제한을 지정할 수 있습니다 itertools.repeat
. 이것은 next
기능에 기본값을 제공하는 것과 결합 될 수 있습니다 .
from itertools import chain, repeat
prompts = chain(["Enter a number:"], repeat("Not a number! Try again:", 2))
replies = map(input, prompts)
valid_response = next(filter(str.isdigit, replies), None)
print("You've failed miserably!" if valid_response is None else 'Well done!')
Enter a number: a
Not a number! Try again: b
Not a number! Try again: c
You've failed miserably!
전처리 입력 데이터 :
때때로 우리는 사용자가 실수로 공급하는 경우 입력을 거부하지 않으려는 대문자 또는 처음에 공백이나 문자열의 끝. 이러한 간단한 실수를 고려하기 위해 str.lower
and str.strip
메소드 를 적용하여 입력 데이터를 사전 처리 할 수 있습니다 . 예를 들어 멤버쉽 테스트의 경우 코드는 다음과 같습니다.
from itertools import chain, repeat
fruits = {'apple', 'orange', 'peach'}
prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
replies = map(input, prompts)
lowercased_replies = map(str.lower, replies)
stripped_replies = map(str.strip, lowercased_replies)
valid_response = next(filter(fruits.__contains__, stripped_replies))
print(valid_response)
Enter a fruit: duck
I don't know this one! Try again: Orange
orange
전처리에 사용할 함수가 많은 경우 함수 구성을 수행하는 함수 를 사용하는 것이 더 쉬울 수 있습니다 . 예를 들어 여기 에서 하나를 사용 하십시오 .
from itertools import chain, repeat
from lz.functional import compose
fruits = {'apple', 'orange', 'peach'}
prompts = chain(["Enter a fruit: "], repeat("I don't know this one! Try again: "))
replies = map(input, prompts)
process = compose(str.strip, str.lower) # you can add more functions here
processed_replies = map(process, replies)
valid_response = next(filter(fruits.__contains__, processed_replies))
print(valid_response)
Enter a fruit: potato
I don't know this one! Try again: PEACH
peach
유효성 검사 규칙 결합 :
예를 들어, 프로그램이 1에서 120 사이의 연령을 요구할 때 간단한 경우에는 다른 것을 추가 할 수 있습니다 filter
.
from itertools import chain, repeat
prompt_msg = "Enter your age (1-120): "
bad_input_msg = "Wrong input."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
numeric_replies = filter(str.isdigit, replies)
ages = map(int, numeric_replies)
positive_ages = filter((0).__lt__, ages)
not_too_big_ages = filter((120).__ge__, positive_ages)
valid_response = next(not_too_big_ages)
print(valid_response)
그러나 규칙이 많은 경우 논리적 결합을 수행하는 함수를 구현하는 것이 좋습니다 . 다음 예제에서는 여기 에서 준비된 것을 사용합니다 .
from functools import partial
from itertools import chain, repeat
from lz.logical import conjoin
def is_one_letter(string: str) -> bool:
return len(string) == 1
rules = [str.isalpha, str.isupper, is_one_letter, 'C'.__le__, 'P'.__ge__]
prompt_msg = "Enter a letter (C-P): "
bad_input_msg = "Wrong input."
prompts = chain([prompt_msg], repeat('\n'.join([bad_input_msg, prompt_msg])))
replies = map(input, prompts)
valid_response = next(filter(conjoin(*rules), replies))
print(valid_response)
Enter a letter (C-P): 5
Wrong input.
Enter a letter (C-P): f
Wrong input.
Enter a letter (C-P): CDE
Wrong input.
Enter a letter (C-P): Q
Wrong input.
Enter a letter (C-P): N
N
누군가가 각 실패한 경우에 사용자 정의 메시지를 필요로하는 경우 불행하게도, 다음, 난 두려워, 어떤이없는 매우 기능적인 방법입니다. 또는 적어도 하나를 찾을 수 없습니다.