Python3.5:如何用一行代码结合三元运算符分类文法终结符与非终结符
解决方案
要在一行代码里完成两个集合的初始化,结合Python3.5+的语法特性,我们有两种简洁的实现方式,满足你的需求:
方式1:使用集合推导式(推荐,更符合Pythonic风格)
这种方式直接通过集合推导式分别生成终结符和非终结符集合,一行完成赋值:
terminals, nonTerminals = set(ch for prod in givenProductions for ch in prod if ch.islower()), set(ch for prod in givenProductions for ch in prod if ch.isupper())
示例验证
对于输入givenProductions = ['S-AA', 'A-a', 'A-b'],运行后:
terminals结果为{'a', 'b'}nonTerminals结果为{'S', 'A'}
如果不想使用islower()/isupper()方法,也可以用你原来的字符范围判断:
terminals, nonTerminals = set(ch for prod in givenProductions for ch in prod if 'a' <= ch <= 'z'), set(ch for prod in givenProductions for ch in prod if 'A' <= ch <= 'Z')
方式2:结合列表推导式与三元运算符
如果你明确要求结合三元运算符,我们可以利用列表推导式遍历所有字符,通过三元分支将字符添加到对应的集合中:
terminals, nonTerminals = set(), set() [terminals.add(ch) if ch.islower() else nonTerminals.add(ch) if ch.isupper() else None for prod in givenProductions for ch in prod]
这里的列表推导式主要用来执行副作用(向集合中添加元素),三元运算符负责判断字符类型,自动忽略掉'-'这类分隔符。
为什么你的原代码行不通?
你尝试的代码用了嵌套循环和append,但列表推导式的核心是生成列表,而非执行副作用操作。另外,你把循环顺序写反了(for ch in prod for prod in givenProductions应该是for prod in givenProductions for ch in prod),这会直接导致语法错误。
内容的提问来源于stack exchange,提问作者Mumbaikar007
相关产品推荐
相关产品推荐

