Python:避免此代码的if条件?
对于以下代码Python:避免此代码的if条件?,python,if-statement,control-flow,Python,If Statement,Control Flow,对于以下代码 a =func() if a != None: b.append(a) a可以指定为None,有没有办法避免if语句而只使用一行代码 最初的问题如下 import xml.etree.ElementTree as etree r = etree.parse(f).getroot() b = etree.Element('register',{}) a = r.find('tag_name') # a may get None if did not find it if
a =func()
if a != None:
b.append(a)
a可以指定为None,有没有办法避免if语句而只使用一行代码
最初的问题如下
import xml.etree.ElementTree as etree
r = etree.parse(f).getroot()
b = etree.Element('register',{})
a = r.find('tag_name') # a may get None if did not find it
if a != None:
b.append(a)
好的,我用了所有的答案,得到了这个,我个人认为这是迄今为止我写过的最复杂的python,哈哈
NS_MAP = {
'spirit' : 'http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4',
'app' : 'http://www.app.com/SPIRIT-app'
}
mp=etree.Element('MemoryProperty', {'version':'alpha'})
mpt=etree.ElementTree(mp)
def copy_tags(tp, op, p, tn, ns='spirit'):
c = p.find('{%s}%s'%(NS_MAP[ns],tn))
if c is not None:
(op == '<-') and tp.append(c)
return c
for reg in regs:
te = etree.Element('register',{})
copy_tags(te,'<-',reg,'name')
copy_tags(te,'<-',reg,'addressOffset')
copy_tags(te,'<-',reg,'access')
(lambda e, t: copy_tags(te,'<-',t,'usageConstraints',ns='app') if t is not None else None)(te, copy_tags(te,'|',reg,'vendorExtensions'))
mp.append(te)
mpt.write('map_gen.xml')
NS\u映射={
"精神":"http://www.spiritconsortium.org/XMLSchema/SPIRIT/1.4',
'应用程序':'http://www.app.com/SPIRIT-app'
}
mp=etree.Element('MemoryProperty',{'version':'alpha'})
mpt=etree.ElementTree(mp)
def副本标签(tp、op、p、tn、ns='spirit'):
c=p.find(“{%s}%s%”(NS_-MAP[NS],tn))
如果c不是无:
(op=='如果可以事先调用func(),并且希望将测试语句和赋值语句组合成一条语句,则可以使用If-else表达式执行此操作:
b += [a] if a is not None else []
如果a不是None,那么这将向b添加[a]——基本上与b.append(a)相同的操作
如果a为None,那么这会将[]添加到b中,从而使b保持不变
除非b是一个列表,或者至少支持“+=”就地加法,否则这将不起作用。如果它不支持-,可能是某个自定义对象,那么您应该能够做到这一点:
(b.append(a) if a is not None else None)
这是一个表达式,计算其副作用,然后丢弃。如果a为None,则永远不会执行b.append(a)
调用。在这两种情况下,表达式的值都为None,但我们不关心它,因此它会被忽略
现在,如果要将func()调用与此结合起来,则必须执行一些不同的操作,以避免调用func两次。如果可以使用“+=”语法,则可以这样做:
b += filter(None, [func()])
filter(None,)
返回删除了所有false元素(不包括任何元素,但也包括0和[])的列表。然后,此语句将向b添加[func()]或[]
[编辑]
最后,对于最坏的情况:如果不能多次调用func(),并且不能使用b+=
,并且需要接受0、“、[]等,并且只排除None
,并且需要在一行中全部调用,那么下面是最难看的代码行:
(lambda l, a: l.append(a) if a is not None else None)(b, func())
这本质上是@ekhumoro的解决方案,压缩成一行。它定义一个匿名函数,调用它,丢弃值,然后丢弃函数,所有这些都是为了产生副作用
现在,这是一行代码,但它肯定不比原始代码更容易阅读和理解。如果我是你,我会坚持原始代码,或者按照@ekhumoro的想法,只定义一个helper函数并使用它。b+=list(set([r.find('tag_name'))-set([None])
但它非常难看。稍微干净一点,但线条也更长:
b.append(r.find('tag_name'))
b.remove(None)
不过还是不是很整洁。如果我是你,我会保留那条If
语句。大概你不是想从代码中删除一条If
语句
因此,显而易见的答案是使用函数:
import xml.etree.ElementTree as etree
def append(parent, child):
if child is not None:
parent.append(child)
r = etree.parse(f).getroot()
b = etree.Element('register',{})
append(b, r.find('tag_name'))
你在这里问错了问题。线索是在你对其中一条评论的回复中,你说“我有10+个标签,如果我能得到3行到1行,我将保存20+行”
因此,您的问题实际上不是有3行代码,而是不必要地反复重复3行代码。您可以使用函数提取重复的代码行,但在这种情况下,您可能实际上需要一个循环:
THE_TAGS = ('tag1', 'tag2', 'and so on')
for tag in THE_TAGS:
a = r.find(tag) # a may get None if did not find it
if a != None:
b.append(a)
或者,如果需要附加到不同的列表:
def extract_tag(r, tag_name, to):
a = r.find(tag_name) # a may get None if did not find it
if a != None:
to.append(a)
extract_tag(r, 'tag1', b)
extract_tag(r, 'tag2', c)
解决您真正的问题,并分两行进行,以清晰明了:
temp = [r.find(tag) for tag in list_of_tags]
b.extend(x for x in temp if x is not None)
注意:Element.extend
在Python2.7/3.2中是新的简短回答:不是真的
更详细的回答:如果您真的想从几个不同的代码块中避免这种情况(可能是因为您想实现这种行为——只追加非None值),那么您可以在底层b对象周围创建一个类作为代理,并在其append方法中隐藏细节
class NonNoneAppender:
def __init__(self, obj):
if not hasattr(obj, 'append') or not callable(obj.append):
raise ValueError, "Object must have append method"
self.__obj = obj
def append(self, item):
if item is not None:
return self.__obj.append(item)
def __getattr__(self, attr):
return getattr( self.__obj, attr)
。。。然后你可以做一些类似的事情:
b = NonNoneAppender(b)
但是,我不确定这对您的代码是否有任何意义。
如果a:=func():b.append(a)
像这样的吗b=[x表示函数列表中的x,如果x不是None]
?很难说清楚你到底想在这里做什么。通常认为使用==或!=将对象与无对象进行比较是个坏主意“是”或“不是”是检查对象是否为无引用的首选方法。(==和!=本质上是将None转换为布尔值、数字值或字符串值进行比较,因此在语义上可能是错误的)。b实际上是xml.etree.ElementTree的一个类,因此,我不确定[]表示法是否有效。我想他是在抱怨这样一个事实,即如果func()的结果不为null,他只想附加该结果。但是,因为他必须检查,所以他在那里有一个笨拙的if语句。@JerryGao:告诉我们你到底在尝试什么。问题是,你在哪里调用func()
?你可能不想给它打几次电话。我真的很想看看这个解决方案,其中,a
被一个只被调用一次的函数调用(在一行中)所取代。b实际上是xml.etree.ElementTree的一个类,所以,我不确定[]符号是否可以工作。为什么不只是b+=[a]如果a else[]……而不是if部分,您仍然需要事先调用a=func()。对不起,我想这是你不喜欢的部分。你在一行中的哪一行加上a=func()。我没有使用的原因是其中一个标记有不同的名称空间,只有一个…@JerryGao:“不同的名称空间”应该不是问题<代码>标记列表=[“{ns1}tag1”,“{ns2}tag2”等]
。请解释一下。@JohnMachin对我来说是taglist=[“{ns1}tag1”、“{ns1}tag2”、“{ns1}tag3”、…、“{ns0}TAG”]@JerryGao:你还没有