有没有办法在python中优化我的if else条件?
if not is_text or not is_archive or not is_hidden or \
not is_system_file or not is_xhtml or not is_audio or not is_video:
is_unrecognised = True
else:
#get the value which is True out of
#is_text, is_archive, is_hidden, is_system_file,
#is_xhtml, is_audio, is_video
我觉得以这种方式编写if条件可能是个坏主意。所以我把它们分成了函数并编写了代码。但是我们可以优化我的代码以使其感觉可读且高效吗?
答案 0 :(得分:4)
“不(A和B)”与“(不是A)或(不是B)”
all(iterable)
:如果iterable的所有元素都为true(或者iterable为空),则返回True。
any(iterable)
:如果iterable的任何元素为true,则返回True。如果iterable为空,则返回False
conditions = ( # make a tuple: an iterable
is_text,
is_archive,
is_hidden,
is_system_file,
is_xhtml,
is_audio,
is_video
)
if not all(conditions): # apply De Morgans
is_unrecognised = True
else:
# other code
顺便说一句,如果符合您的要求,可以进一步简化,而不是
is_unrecognised = not all(conditions)
# may be you can write
# if not is_unrecognised:
# you code in else
答案 1 :(得分:3)
布尔代数满足De Morgan定律,
(De Morgan 1) (¬x)∧(¬y) = ¬(x∨y)
(De Morgan 2) (¬x)∨(¬y) = ¬(x∧y).
因此您可以将其更改为
if not ( is_text and is_archive and is_hidden and is_system_file and is_xhtml and is_audio and is_video):
is_unrecognised = True
else:
#get the value which is True out of
#is_text, is_archive, is_hidden, is_system_file,
#is_xhtml, is_audio, is_video
答案 2 :(得分:3)
首先,我会尝试使用try: except:
而不是if: else:
。它更快,因为我不完全理解。唯一的问题是你的陈述必须提高异常。
另一种方法是这样做:
if False in [is_text, is_archive, is_hidden, is_system_file, is_xhtml, is_audio, is_video]:
答案 3 :(得分:3)
看起来你必须确切地知道哪些条件是真的。在这种情况下,我建议像这样写:
if is_text:
# do something
elif is_archive:
...
elif is_video:
# do something
else:
is_unrecognised = True
此结构类似于其他语言中的switch
或case
语句。
修改:是的,正如评论中所建议的那样,您的原始代码可能包含and
而不是or
。所以它就像:如果它是(1)不是文字和(2)不是视频和(...)不是所有其他可识别的东西,那么它未被承认。
答案 4 :(得分:1)
我认为最简单和Pythonic的做法是对@Grijesh的回答进行一些修改。即,
conditions = (
is_text,
is_archive,
is_hidden,
is_system_file,
is_xhtml,
is_audio,
is_video
)
is_unrecognised = True if not any(conditions) else False
答案 5 :(得分:1)
到目前为止,其他人说的是正确的,您可以使用De Morgan's laws并重写if测试。
但是,据我所知,目前最大的问题是,如果我正确理解你的代码,它就不会按照你的想法做到。
你真正想要的似乎是
if not (is_text or is_archive or is_hidden or \
is_system_file or is_xhtml or is_audio or is_video):
is_unrecognised = True
或
if not any(is_text, is_archive, is_hidden, is_system_file, is_xhtml, is_audio, is_video):
is_unrecognised = True
编辑:或者Gassa的解决方案似乎更符合您实际尝试的目标。
答案 6 :(得分:1)
您的数据表示可能会让您误入歧途。如果相反你做了像
这样的事情tests = dict()
testkeys = ['text', 'archive', 'hidden', 'system', 'xhtml', 'audio', 'video']
[tests[i] = False for i in testkeys]
# whatever code you have now to set is_text should now instead set tests['text'], etc
if not True in tests.values():
is_unrecognized = True
else:
recognized = [k for k in tests if tests[k] is True] # f'rinstance
(我确信有更多惯用的方法可以做到这一点。只是建议一种不同的思维模式,真的。)
答案 7 :(得分:1)
即使这个问题已经得到解答。我提出了一个替代方案,其中包含问题代码中的注释。
正如@tripleee所指出的,代码注释中提出的原始问题是获取值为True的变量。
@ tripleee的答案假设用变量名创建一个字典。
另一种方法是从locals
获取名称。以下代码
is_text = False
is_archive = True
is_hidden = False
is_system_file = False
is_xhtml = False
is_audio = True
is_video = False
the_size = 34 # <- note also this
conditions = (
is_text,
is_archive,
is_hidden,
is_system_file,
is_xhtml,
is_audio,
is_video,
the_size,
)
result = [(k, v) for k, v in list(locals().iteritems()) \
if id(v) in [id(condition) for condition in conditions] and v]
if len(result) == 0:
is_unrecognized = True
else:
# do what you want with your variables which have value True
# as example print the variable names and values
for k, v in result:
print 'variable "%s" is %s' % (k, v)