Python:在这段代码中避免if条件?

lsmepo6l  于 2022-12-28  发布在  Python
关注(0)|答案(8)|浏览(179)

对于以下代码

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')
v6ylcynt

v6ylcynt1#

如果你可以事先调用func(),并且你想把test和assignment语句合并成一条语句,那么你可以使用if-else表达式来实现这一点:

b += [a] if a is not None else []

如果a不是None,那么这将把[a]加到B上--本质上与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, <list>)返回去掉所有false元素的列表(不包括任何元素,但也包括0和[]),然后这个语句将[func()]或[]添加到b中。

[编辑]

最后,对于最坏情况:如果你不能多次调用func(),* 和 * 你不能使用b += <list>,* 和 * 你需要接受0,“",[]等,并且只排除None,* 和 * 你需要在一行中完成所有操作,这是迄今为止最难看的一行代码:

(lambda l, a: l.append(a) if a is not None else None)(b, func())

这基本上是@ekhumoro的解决方案,压缩成一行,定义一个匿名函数,调用它,丢弃值,然后丢弃函数,所有这些都是为了副作用。
这是一行代码,但是它肯定不会比原始代码更容易阅读和理解,如果我是你,我会坚持原始代码,或者接受@ekhumoro的想法,定义一个辅助函数并使用它。

holgip5t

holgip5t3#

你在这里问错了问题。线索就在你对其中一条评论的回复中,你说“我有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)
db2dz4w8

db2dz4w84#

简短回答:不太喜欢。
更长的答案:如果你真的想避免这种情况(也许是因为你想在几个不同的代码块中实现这种行为---只附加非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)

但是,我不确定这对您的代码是否有任何意义。

mcvgt66p

mcvgt66p5#

攻击你真实的的问题,为了清晰起见,分两行:

temp = [r.find(tag) for tag in list_of_tags]
b.extend(x for x in temp if x is not None)

注意:Element.extend是Python 2.7/3.2中的新增功能

mzaanser

mzaanser6#

假设您不想从代码中删除一条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'))
a9wyjsp7

a9wyjsp77#

你可以只添加所有内容,然后在b = [a for a in b if b is not None]的末尾删除None。或者,在你的特定用例中,你可以执行b.extend(r.findall('tag_name')[:1])。但是,这可能会有点慢,因为它将遍历整个树,而不是在第一个示例处停止。

eoxn13cs

eoxn13cs8#

第一个月
但很难看。干净一点,但线条也长了一点:

b.append(r.find('tag_name'))
b.remove(None)

不过还是不太整洁,如果我是你,我会保留if语句。

相关问题