[PYTHON] 파이썬에서 간단한 부울 논리를 동적으로 평가하기
PYTHON파이썬에서 간단한 부울 논리를 동적으로 평가하기
다음과 같이 동적으로 생성 된 부울 논리 표현식이 있습니다.
자리 표시자는 부울로 바뀝니다. 해야합니까?
제안을 환영합니다.
해결법
-
==============================
1.예를 들어 pyparsing을 사용하여이를 처리 할 수있는 평가기를 작성하는 것이 전혀 어렵지는 않습니다. 처리 할 연산이 몇 개 밖에 없으므로 (및 또는 그룹화?), 직접 구문 분석하고 평가할 수 있어야합니다.
예를 들어 pyparsing을 사용하여이를 처리 할 수있는 평가기를 작성하는 것이 전혀 어렵지는 않습니다. 처리 할 연산이 몇 개 밖에 없으므로 (및 또는 그룹화?), 직접 구문 분석하고 평가할 수 있어야합니다.
표현식을 평가하기 위해 명시 적으로 이진 트리를 형성 할 필요는 없습니다.
-
==============================
2.다음은 약 1 시간 반 (리팩토링에 거의 1 시간 정도)으로 작성된 작은 모듈 (공백을 포함하여 74 줄)입니다.
다음은 약 1 시간 반 (리팩토링에 거의 1 시간 정도)으로 작성된 작은 모듈 (공백을 포함하여 74 줄)입니다.
str_to_token = {'True':True, 'False':False, 'and':lambda left, right: left and right, 'or':lambda left, right: left or right, '(':'(', ')':')'} empty_res = True def create_token_lst(s, str_to_token=str_to_token): """create token list: 'True or False' -> [True, lambda..., False]""" s = s.replace('(', ' ( ') s = s.replace(')', ' ) ') return [str_to_token[it] for it in s.split()] def find(lst, what, start=0): return [i for i,it in enumerate(lst) if it == what and i >= start] def parens(token_lst): """returns: (bool)parens_exist, left_paren_pos, right_paren_pos """ left_lst = find(token_lst, '(') if not left_lst: return False, -1, -1 left = left_lst[-1] #can not occur earlier, hence there are args and op. right = find(token_lst, ')', left + 4)[0] return True, left, right def bool_eval(token_lst): """token_lst has length 3 and format: [left_arg, operator, right_arg] operator(left_arg, right_arg) is returned""" return token_lst[1](token_lst[0], token_lst[2]) def formatted_bool_eval(token_lst, empty_res=empty_res): """eval a formatted (i.e. of the form 'ToFa(ToF)') string""" if not token_lst: return empty_res if len(token_lst) == 1: return token_lst[0] has_parens, l_paren, r_paren = parens(token_lst) if not has_parens: return bool_eval(token_lst) token_lst[l_paren:r_paren + 1] = [bool_eval(token_lst[l_paren+1:r_paren])] return formatted_bool_eval(token_lst, bool_eval) def nested_bool_eval(s): """The actual 'eval' routine, if 's' is empty, 'True' is returned, otherwise 's' is evaluated according to parentheses nesting. The format assumed: [1] 'LEFT OPERATOR RIGHT', where LEFT and RIGHT are either: True or False or '(' [1] ')' (subexpression in parentheses) """ return formatted_bool_eval(create_token_lst(s))
간단한 테스트 결과는 다음과 같습니다.
>>> print nested_bool_eval('') True >>> print nested_bool_eval('False') False >>> print nested_bool_eval('True or False') True >>> print nested_bool_eval('True and False') False >>> print nested_bool_eval('(True or False) and (True or False)') True >>> print nested_bool_eval('(True or False) and (True and False)') False >>> print nested_bool_eval('(True or False) or (True and False)') True >>> print nested_bool_eval('(True and False) or (True and False)') False >>> print nested_bool_eval('(True and False) or (True and (True or False))') True
[부분적으로 화제가 될 가능성이 있음]
token_to_char = token_to_char와 friends가 제공하는 poor-mans 의존성 주입 수단과 함께 사용하는 토큰 (피연산자와 연산자 모두)을 동시에 여러 개의 다른 평가자를 가질 수 있도록 쉽게 구성 할 수 있습니다 ( "주입 - 기본적으로 "전역"은 단일 동작으로 남겨 둡니다).
예 :
def fuzzy_bool_eval(s): """as normal, but: - an argument 'Maybe' may be :)) present - algebra is: [one of 'True', 'False', 'Maybe'] [one of 'or', 'and'] 'Maybe' -> 'Maybe' """ Maybe = 'Maybe' # just an object with nice __str__ def or_op(left, right): return (Maybe if Maybe in [left, right] else (left or right)) def and_op(left, right): args = [left, right] if Maybe in args: if True in args: return Maybe # Maybe and True -> Maybe else: return False # Maybe and False -> False return left and right str_to_token = {'True':True, 'False':False, 'Maybe':Maybe, 'and':and_op, 'or':or_op, '(':'(', ')':')'} token_lst = create_token_lst(s, str_to_token=str_to_token) return formatted_bool_eval(token_lst)
제공 :
>>> print fuzzy_bool_eval('') True >>> print fuzzy_bool_eval('Maybe') Maybe >>> print fuzzy_bool_eval('True or False') True >>> print fuzzy_bool_eval('True or Maybe') Maybe >>> print fuzzy_bool_eval('False or (False and Maybe)') False
-
==============================
3.관심이있는 지역 및 전역 변수로 딕테이션을 설정하면 eval ()에 표현식과 함께 전달할 수 있어야합니다.
관심이있는 지역 및 전역 변수로 딕테이션을 설정하면 eval ()에 표현식과 함께 전달할 수 있어야합니다.
-
==============================
4.SymPy 로직 모듈을 사용하는 케이크 조각처럼 들립니다. 그들은 심지어 그 문서의 예를 가지고 있습니다 : http://docs.sympy.org/0.7.1/modules/logic.html
SymPy 로직 모듈을 사용하는 케이크 조각처럼 들립니다. 그들은 심지어 그 문서의 예를 가지고 있습니다 : http://docs.sympy.org/0.7.1/modules/logic.html
from https://stackoverflow.com/questions/2467590/dynamically-evaluating-simple-boolean-logic-in-python by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 요청 파이썬 라이브러리에서 HTTP 요청의 다운로드 속도를 제한하는 방법은 무엇입니까? (0) | 2018.11.16 |
---|---|
[PYTHON] 파이썬 : 유니 코드 문자열을 살균 하시겠습니까? [복제] (0) | 2018.11.16 |
[PYTHON] PHP 스크립트에서 Python 스크립트로 값 전달하기 (0) | 2018.11.16 |
[PYTHON] 'int'유형의 목록에있는 모든 항목을 테스트하는 방법은 무엇입니까? (0) | 2018.11.16 |
[PYTHON] 전체 페이지를 다운로드하지 않고 웹 페이지가 있는지 확인하는 Python 스크립트? (0) | 2018.11.16 |