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:你还没有