簡體   English   中英

從字典中獲取列表中元素的True或False值

[英]Getting True or False value for elements in a list from a dictionary

假設我們有以下變量:

my_list = ["door_open", "AND", "dog_gone"], 
my_dict ={"door_open" : "false", "dog_gone" : "true", "dog_asleep" : "true"})

(請注意,列表和字典可以更長或更短,並且仍然可以使用)。 我們希望能夠通過以下功能運行它:

def and_function(arg1, arg2):
    if arg1=="true" and arg2=="true":
        return "true"
    else:
        return "false"

我們如何編寫一個函數,該函數首先將檢查列表中的元素是“ true”還是“ false”,然后通過“ and_function”運行它。 這看起來應該是這樣的:

def interpret(my_list, my_dict):
#DO SOMETHING SO WE GET THE "true" OR "false" VALUE FOR ELEMENTS
.
. 
. 
if "AND" in my_list:
    return and_function(ture_or_false, false_or_true) 


"false"

這看起來像遞歸結構(因為操作數也可能是表達式)。 在這種情況下,編寫解析器是一個好主意。 但是,自己編寫解析器通常容易出錯且麻煩。 因此,我們不會自己編寫解析器,而是使用可以指定規格的工具,然后生成解析器本身。

這些工具之一是例如PLY 一個簡單的解析器(我將不實現完整的解析器,但思路應該很清楚),如下所示。

詞法分析器

首先,我們需要實現一個分析令牌的詞法分析器:

# lexer.py

import ply.lex as lex

tokens = (
    'AND',
    'OR',
    'IDENTIFIER',
)

t_AND = r'AND'
t_OR = r'OR'

def t_IDENTIFIER(t):
    r'[a-z_]+'  
    return t

t_ignore  = ' \t\r\n'

lexer = lex.lex()

上面的代碼將導致一個詞法分析器 (也稱為標記器 ;不是解析器)。 詞法分析器將字符串轉換為令牌列表。 這里有三個可能的標記: ANDORIDENTIFIER AND僅匹配'AND' (大寫), OR匹配“ OR”(大寫), IDENTIFIER匹配任何由小寫字符和下划線組成的序列。

因此,如果我們解析一個字符串,則會得到:

>>> from lexer import lexer
>>> lexer.input('foo AND bar')
>>> lexer.token()
LexToken(IDENTIFIER,'foo',1,0)
>>> lexer.token()
LexToken(AND,'AND',1,4)
>>> lexer.token()
LexToken(IDENTIFIER,'bar',1,8)
>>> lexer.token()
>>>

解析器

現在,我們可以將令牌列表變成一個包含葉子(標識符)和索引節點 (操作數)的“樹”:

# parser.py

import ply.yacc as yacc

class Identifier:

    def __init__(self, name):
        self.name = name

    def resolve(self, dictionary):
        return dictionary[self.name]

class Node:

    def __init__(self, left, right):
        self.left = left
        self.right = right

    def resolve(self, dictionary):
        return self.func(self.left.resolve(dictionary), self.right.resolve(dictionary))

    def func(self, left, right):
        return None

class AndNode(Node):

    def func(self, left, right):
        return left and right

class OrNode(Node):

    def func(self, left, right):
        return left or right

from lexer import tokens

def p_expression_or(p):
    'expression : and_exp OR expression'
    p[0] = OrNode(p[1], p[3])

def p_expression_or_no(p):
    'expression : and_exp'
    p[0] = p[1]

def p_expression_and(p):
    'and_exp : ident AND and_exp'
    p[0] = AndNode(p[1], p[3])

def p_expression_and_no(p):
    'and_exp : ident'
    p[0] = p[1]

def p_ident(p):
    'ident : IDENTIFIER'
    p[0] = Identifier(p[1])

parser = yacc.yacc()

在這里,我們指定了一組生產規則以及處理該生產規則的邏輯。 我們指定一個expressionand_expr后跟一個OR然后是另一個expression (第一個函數),或者只是一個and_expr (第二個函數)。 因此,我們建立了語言的語法。 在函數中,我們以樹形方式構造了AndNodeOrNodeIdentifier對象。

評估語法樹

現在我們可以將字符串解析為這樣的樹:

from parser import parser

tree = parser.parse('foo AND bar')

現在有一個像這樣的字典:

data = {'foo': True, 'bar': True}

我們可以調用tree.resolve(..)方法,並獲取結果:

>>> tree.resolve({'foo': True, 'bar': True})
True
>>> tree.resolve({'foo': True, 'bar': False})
False
>>> tree.resolve({'foo': False, 'bar': False})
False 

擴展解析器

如果您閱讀該文檔,則將找到將括號和其他函數(一元運算符,二進制運算符,函數)等包括到詞法分析器,解析器中並對其進行評估的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM