标签归档:if-statement

如何检查字符串是否包含Python中列表中的元素

问题:如何检查字符串是否包含Python中列表中的元素

我有这样的事情:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

我想知道在Python中(不使用for循环)更优雅的方法是什么?我在想这样的事情(例如从C / C ++开始),但是没有用:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

编辑:我有点被迫解释这与下面的问题有何不同,该问题被标记为潜在重复(所以我猜它不会关闭)。

区别是,我想检查一个字符串是否是某些字符串列表的一部分,而另一个问题是检查字符串列表中的字符串是否是另一个字符串的子字符串。类似的,但不完全相同,当您在网上寻找答案时,语义很重要。这两个问题实际上是在寻求解决彼此相反的问题。两者的解决方案虽然相同。

I have something like this:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

I am wondering what would be the more elegant way to do this in Python (without using the for loop)? I was thinking of something like this (like from C/C++), but it didn’t work:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

Edit: I’m kinda forced to explain how this is different to the question below which is marked as potential duplicate (so it doesn’t get closed I guess).

The difference is, I wanted to check if a string is part of some list of strings whereas the other question is checking whether a string from a list of strings is a substring of another string. Similar, but not quite the same and semantics matter when you’re looking for an answer online IMHO. These two questions are actually looking to solve the opposite problem of one another. The solution for both turns out to be the same though.


回答 0

与一起使用生成器any,它会在第一个True上短路:

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

编辑:我看到这个答案已经被OP接受。尽管我的解决方案可能是解决他特定问题的“足够好”的解决方案,并且是检查列表中是否有任何字符串在另一个字符串中找到的一种很好的通用方法,但请记住,这就是该解决方案的全部工作。不管在哪里找到字符串,例如在字符串的末尾。如果这很重要(通常是使用url的情况),则应查看@Wladimir Palant的答案,否则,您可能会得到误报。

Use a generator together with any, which short-circuits on the first True:

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

EDIT: I see this answer has been accepted by OP. Though my solution may be “good enough” solution to his particular problem, and is a good general way to check if any strings in a list are found in another string, keep in mind that this is all that this solution does. It does not care WHERE the string is found e.g. in the ending of the string. If this is important, as is often the case with urls, you should look to the answer of @Wladimir Palant, or you risk getting false positives.


回答 1

extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False

回答 2

这是更好地解析正确的URL -这种方式,您可以处理http://.../file.doc?foohttp://.../foo.doc/file.exe正确。

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

It is better to parse the URL properly – this way you can handle http://.../file.doc?foo and http://.../foo.doc/file.exe correctly.

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

回答 3

如果需要单行解决方案,请使用列表推导。以下代码在扩展名为.doc,.pdf和.xls时返回包含url_string的列表,或者在不包含扩展名时返回空列表。

print [url_string for extension in extensionsToCheck if(extension in url_string)]

注意:这仅是检查它是否包含,并且在想要提取与扩展名匹配的确切单词时无用。

Use list comprehensions if you want a single line solution. The following code returns a list containing the url_string when it has the extensions .doc, .pdf and .xls or returns empty list when it doesn’t contain the extension.

print [url_string for extension in extensionsToCheck if(extension in url_string)]

NOTE: This is only to check if it contains or not and is not useful when one wants to extract the exact word matching the extensions.


回答 4

检查它是否与此正则表达式匹配:

'(\.pdf$|\.doc$|\.xls$)'

注意:如果扩展名不在URL的末尾,请删除$字符,但这会稍微削弱它

Check if it matches this regex:

'(\.pdf$|\.doc$|\.xls$)'

Note: if you extensions are not at the end of the url, remove the $ characters, but it does weaken it slightly


回答 5

这是@psun给出的列表理解答案的一种变体。

通过切换输出值,您实际上可以从列表理解中提取匹配的模式(any()@ Lauritz-v-Thaulow 的方法无法做到这一点)

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

[‘.doc’]`

如果想要在知道匹配的模式后收集其他信息,则可以进一步插入正则表达式(当允许的模式列表太长而无法写入单个regex模式时,这可能会很有用)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

This is a variant of the list comprehension answer given by @psun.

By switching the output value, you can actually extract the matching pattern from the list comprehension (something not possible with the any() approach by @Lauritz-v-Thaulow)

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

[‘.doc’]`

You can furthermore insert a regular expression if you want to collect additional information once the matched pattern is known (this could be useful when the list of allowed patterns is too long to write into a single regex pattern)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']


Python如果不是== vs如果!=

问题:Python如果不是== vs如果!=

这两行代码有什么区别:

if not x == 'val':

if x != 'val':

一个比另一个更有效吗?

会更好用吗

if x == 'val':
    pass
else:

What is the difference between these two lines of code:

if not x == 'val':

and

if x != 'val':

Is one more efficient than the other?

Would it be better to use

if x == 'val':
    pass
else:

回答 0

使用dis一下两个版本生成的字节码:

not ==

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 RETURN_VALUE   

!=

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 RETURN_VALUE   

后者的操作较少,因此效率可能会略高一些。


致谢中指出了(感谢@Quincunx),您所进行的操作if foo != barif not foo == bar操作数量完全相同,只是COMPARE_OP更改并POP_JUMP_IF_TRUE切换为POP_JUMP_IF_FALSE

not ==

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 POP_JUMP_IF_TRUE        16

!=

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 POP_JUMP_IF_FALSE       16

在这种情况下,除非每次比较所需的工作量有所不同,否则您根本看不到任何性能差异。


但是,请注意,这两个版本在逻辑上并不总是相同的,因为这将取决于所涉及对象的实现__eq____ne__针对对象的实现。根据数据模型文档

比较运算符之间没有隐含的关系。的真相x==y并不意味着那x!=y是错误的。

例如:

>>> class Dummy(object):
    def __eq__(self, other):
        return True
    def __ne__(self, other):
        return True


>>> not Dummy() == Dummy()
False
>>> Dummy() != Dummy()
True

最后,也许是最重要的一点:通常,两者逻辑上是相同的,x != y但比更具可读性not x == y

Using dis to look at the bytecode generated for the two versions:

not ==

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 RETURN_VALUE   

!=

  4           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 RETURN_VALUE   

The latter has fewer operations, and is therefore likely to be slightly more efficient.


It was pointed out in the commments (thanks, @Quincunx) that where you have if foo != bar vs. if not foo == bar the number of operations is exactly the same, it’s just that the COMPARE_OP changes and POP_JUMP_IF_TRUE switches to POP_JUMP_IF_FALSE:

not ==:

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               2 (==)
              9 POP_JUMP_IF_TRUE        16

!=

  2           0 LOAD_FAST                0 (foo)
              3 LOAD_FAST                1 (bar)
              6 COMPARE_OP               3 (!=)
              9 POP_JUMP_IF_FALSE       16

In this case, unless there was a difference in the amount of work required for each comparison, it’s unlikely you’d see any performance difference at all.


However, note that the two versions won’t always be logically identical, as it will depend on the implementations of __eq__ and __ne__ for the objects in question. Per the data model documentation:

There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false.

For example:

>>> class Dummy(object):
    def __eq__(self, other):
        return True
    def __ne__(self, other):
        return True


>>> not Dummy() == Dummy()
False
>>> Dummy() != Dummy()
True

Finally, and perhaps most importantly: in general, where the two are logically identical, x != y is much more readable than not x == y.


回答 1

@jonrsharpe对发生的事情有很好的解释。我以为只是将3个选项中的每一个运行10,000,000次时,就会显示出时间差异(足以显示出一点差异)。

使用的代码:

def a(x):
    if x != 'val':
        pass


def b(x):
    if not x == 'val':
        pass


def c(x):
    if x == 'val':
        pass
    else:
        pass


x = 1
for i in range(10000000):
    a(x)
    b(x)
    c(x)

和cProfile事件探查器结果:

因此,我们可以看到有间〜0.7%的非常微小差别if not x == 'val':if x != 'val':。其中,if x != 'val':是最快的。

但是,最令人惊讶的是,我们可以看到

if x == 'val':
        pass
    else:

实际上是最快的,胜过if x != 'val':〜0.3%。这不是很容易理解,但是我想如果您想忽略不计的性能改进,可以采用这种方法。

@jonrsharpe has an excellent explanation of what’s going on. I thought I’d just show the difference in time when running each of the 3 options 10,000,000 times (enough for a slight difference to show).

Code used:

def a(x):
    if x != 'val':
        pass


def b(x):
    if not x == 'val':
        pass


def c(x):
    if x == 'val':
        pass
    else:
        pass


x = 1
for i in range(10000000):
    a(x)
    b(x)
    c(x)

And the cProfile profiler results:

So we can see that there is a very minute difference of ~0.7% between if not x == 'val': and if x != 'val':. Of these, if x != 'val': is the fastest.

However, most surprisingly, we can see that

if x == 'val':
        pass
    else:

is in fact the fastest, and beats if x != 'val': by ~0.3%. This isn’t very readable, but I guess if you wanted a negligible performance improvement, one could go down this route.


回答 2

在第一个Python中,Python必须执行比必要更多的操作(而不是仅检查不等于它,而是必须检查它是否相等,因此还要执行一个操作)。不可能说出一次执行的区别,但是如果执行多次,第二次执行将更有效率。总的来说,我会用第二个,但从数学上讲它们是相同的

In the first one Python has to execute one more operations than necessary(instead of just checking not equal to it has to check if it is not true that it is equal, thus one more operation). It would be impossible to tell the difference from one execution, but if run many times, the second would be more efficient. Overall I would use the second one, but mathematically they are the same


回答 3

>>> from dis import dis
>>> dis(compile('not 10 == 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT
             10 POP_TOP
             11 LOAD_CONST               2 (None)
             14 RETURN_VALUE
>>> dis(compile('10 != 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               3 (!=)
              9 POP_TOP
             10 LOAD_CONST               2 (None)
             13 RETURN_VALUE

在这里您可以看到该not x == y指令比的指令多x != y。因此,除非您进行数百万次比较,否则在大多数情况下,性能差异将很小,即使这样,也可能不会成为瓶颈。

>>> from dis import dis
>>> dis(compile('not 10 == 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT
             10 POP_TOP
             11 LOAD_CONST               2 (None)
             14 RETURN_VALUE
>>> dis(compile('10 != 20', '', 'exec'))
  1           0 LOAD_CONST               0 (10)
              3 LOAD_CONST               1 (20)
              6 COMPARE_OP               3 (!=)
              9 POP_TOP
             10 LOAD_CONST               2 (None)
             13 RETURN_VALUE

Here you can see that not x == y has one more instruction than x != y. So the performance difference will be very small in most cases unless you are doing millions of comparisons and even then this will likely not be the cause of a bottleneck.


回答 4

另一个需要注意的是,由于其他答案大多可以正确回答您的问题,因此,如果仅定义一个类__eq__()而不是__ne__(),则您COMPARE_OP (!=)将运行__eq__()并取反它。到那时,您的第三个选择可能会更有效率,但只有在需要速度时才应考虑使用,因为这很难快速理解。

An additional note, since the other answers answered your question mostly correctly, is that if a class only defines __eq__() and not __ne__(), then your COMPARE_OP (!=) will run __eq__() and negate it. At that time, your third option is likely to be a tiny bit more efficient, but should only be considered if you NEED the speed, since it’s difficult to understand quickly.


回答 5

这是关于您的阅读方式。not操作符是动态的,这就是为什么您可以将其应用于

if not x == 'val':

但是!=作为一个相反的运算符,可以更好地理解==它。

It’s about your way of reading it. not operator is dynamic, that’s why you are able to apply it in

if not x == 'val':

But != could be read in a better context as an operator which does the opposite of what == does.


回答 6

我想在上面扩展我的可读性注释。

再次,我完全同意可读性优先于其他(性能无关紧要)的问题。

我想指出的是,大脑对“阳性”的解释比对“阴性”的解释要快。例如,“停止”与“不走”(由于单词数量的差异,这是一个很糟糕的例子)。

因此有一个选择:

if a == b
    (do this)
else
    (do that)

在功能上等效于:

if a != b
    (do that)
else
    (do this)

较低的可读性/可理解性导致更多的错误。也许不是在初始编码中,而是(不如您聪明!)维护发生了变化…

I want to expand on my readability comment above.

Again, I completely agree with readability overriding other (performance-insignificant) concerns.

What I would like to point out is the brain interprets “positive” faster than it does “negative”. E.g., “stop” vs. “do not go” (a rather lousy example due to the difference in number of words).

So given a choice:

if a == b
    (do this)
else
    (do that)

is preferable to the functionally-equivalent:

if a != b
    (do that)
else
    (do this)

Less readability/understandability leads to more bugs. Perhaps not in initial coding, but the (not as smart as you!) maintenance changes…


结合FOR循环和IF语句的Python方法

问题:结合FOR循环和IF语句的Python方法

我知道如何在单独的行上同时使用for循环和if语句,例如:

>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
...     if x in a:
...         print(x)
0,4,6,7,9

而且我知道当语句很简单时,我可以使用列表推导来组合这些内容,例如:

print([x for x in xyz if x in a])

但是,我找不到任何地方(复制和学习)的好例子,展示了一组复杂的命令(不仅是“ print x”),这些命令是在for循环和某些if语句组合后发生的。我期望的是:

for x in xyz if x not in a:
    print(x...)

难道这不是python应该工作的方式吗?

I know how to use both for loops and if statements on separate lines, such as:

>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
...     if x in a:
...         print(x)
0,4,6,7,9

And I know I can use a list comprehension to combine these when the statements are simple, such as:

print([x for x in xyz if x in a])

But what I can’t find is a good example anywhere (to copy and learn from) demonstrating a complex set of commands (not just “print x”) that occur following a combination of a for loop and some if statements. Something that I would expect looks like:

for x in xyz if x not in a:
    print(x...)

Is this just not the way python is supposed to work?


回答 0

您可以使用以下生成器表达式

gen = (x for x in xyz if x not in a)

for x in gen:
    print x

You can use generator expressions like this:

gen = (x for x in xyz if x not in a)

for x in gen:
    print x

回答 1

按照《 Python的禅宗》(如果您想知道代码是否是“ Pythonic”,那就去吧):

  • 美丽胜于丑陋。
  • 显式胜于隐式。
  • 简单胜于复杂。
  • 扁平比嵌套更好。
  • 可读性很重要。

获得两个s 的Pythonic方法是:sorted intersectionset

>>> sorted(set(a).intersection(xyz))
[0, 4, 6, 7, 9]

或那些xyz不在中的元素a

>>> sorted(set(xyz).difference(a))
[12, 242]

但是对于更复杂的循环,您可能希望通过迭代名称良好的生成器表达式和/或调出名称良好的函数来使其扁平化。试图将所有内容都放在一条线上很少是“ Pythonic”的。


在对您的问题和已接受的答案进行其他评论后进行更新

我不确定您要使用的是什么enumerate,但是如果a是字典,则可能要使用这些键,如下所示:

>>> a = {
...     2: 'Turtle Doves',
...     3: 'French Hens',
...     4: 'Colly Birds',
...     5: 'Gold Rings',
...     6: 'Geese-a-Laying',
...     7: 'Swans-a-Swimming',
...     8: 'Maids-a-Milking',
...     9: 'Ladies Dancing',
...     0: 'Camel Books',
... }
>>>
>>> xyz = [0, 12, 4, 6, 242, 7, 9]
>>>
>>> known_things = sorted(set(a.iterkeys()).intersection(xyz))
>>> unknown_things = sorted(set(xyz).difference(a.iterkeys()))
>>>
>>> for thing in known_things:
...     print 'I know about', a[thing]
...
I know about Camel Books
I know about Colly Birds
I know about Geese-a-Laying
I know about Swans-a-Swimming
I know about Ladies Dancing
>>> print '...but...'
...but...
>>>
>>> for thing in unknown_things:
...     print "I don't know what happened on the {0}th day of Christmas".format(thing)
...
I don't know what happened on the 12th day of Christmas
I don't know what happened on the 242th day of Christmas

As per The Zen of Python (if you are wondering whether your code is “Pythonic”, that’s the place to go):

  • Beautiful is better than ugly.
  • Explicit is better than implicit.
  • Simple is better than complex.
  • Flat is better than nested.
  • Readability counts.

The Pythonic way of getting the sorted intersection of two sets is:

>>> sorted(set(a).intersection(xyz))
[0, 4, 6, 7, 9]

Or those elements that are xyz but not in a:

>>> sorted(set(xyz).difference(a))
[12, 242]

But for a more complicated loop you may want to flatten it by iterating over a well-named generator expression and/or calling out to a well-named function. Trying to fit everything on one line is rarely “Pythonic”.


Update following additional comments on your question and the accepted answer

I’m not sure what you are trying to do with enumerate, but if a is a dictionary, you probably want to use the keys, like this:

>>> a = {
...     2: 'Turtle Doves',
...     3: 'French Hens',
...     4: 'Colly Birds',
...     5: 'Gold Rings',
...     6: 'Geese-a-Laying',
...     7: 'Swans-a-Swimming',
...     8: 'Maids-a-Milking',
...     9: 'Ladies Dancing',
...     0: 'Camel Books',
... }
>>>
>>> xyz = [0, 12, 4, 6, 242, 7, 9]
>>>
>>> known_things = sorted(set(a.iterkeys()).intersection(xyz))
>>> unknown_things = sorted(set(xyz).difference(a.iterkeys()))
>>>
>>> for thing in known_things:
...     print 'I know about', a[thing]
...
I know about Camel Books
I know about Colly Birds
I know about Geese-a-Laying
I know about Swans-a-Swimming
I know about Ladies Dancing
>>> print '...but...'
...but...
>>>
>>> for thing in unknown_things:
...     print "I don't know what happened on the {0}th day of Christmas".format(thing)
...
I don't know what happened on the 12th day of Christmas
I don't know what happened on the 242th day of Christmas

回答 2

我个人认为这是最漂亮的版本:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
for x in filter(lambda w: w in a, xyz):
  print x

编辑

如果您非常想避免使用lambda,则可以使用部分函数应用程序并使用运算符模块(该模块提供大多数运算符的功能)。

https://docs.python.org/2/library/operator.html#module-operator

from operator import contains
from functools import partial
print(list(filter(partial(contains, a), xyz)))

I personally think this is the prettiest version:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
for x in filter(lambda w: w in a, xyz):
  print x

Edit

if you are very keen on avoiding to use lambda you can use partial function application and use the operator module (that provides functions of most operators).

https://docs.python.org/2/library/operator.html#module-operator

from operator import contains
from functools import partial
print(list(filter(partial(contains, a), xyz)))

回答 3

以下是接受的答案的一种简化/一种解释:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]

for x in (x for x in xyz if x not in a):
    print(x)

12
242

请注意,generator保持内联。已在python2.7python3.6 (请注意print;)中的括号中对此进行了测试)

The following is a simplification/one liner from the accepted answer:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]

for x in (x for x in xyz if x not in a):
    print(x)

12
242

Notice that the generator was kept inline. This was tested on python2.7 and python3.6 (notice the parens in the print ;) )


回答 4

我可能会使用:

for x in xyz: 
    if x not in a:
        print x...

I would probably use:

for x in xyz: 
    if x not in a:
        print x...

回答 5

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]  
set(a) & set(xyz)  
set([0, 9, 4, 6, 7])
a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]  
set(a) & set(xyz)  
set([0, 9, 4, 6, 7])

回答 6

如果生成器表达式变得过于复杂或复杂,您也可以使用生成器:

def gen():
    for x in xyz:
        if x in a:
            yield x

for x in gen():
    print x

You can use generators too, if generator expressions become too involved or complex:

def gen():
    for x in xyz:
        if x in a:
            yield x

for x in gen():
    print x

回答 7

使用intersectionintersection_update

  • 交叉点

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    ans = sorted(set(a).intersection(set(xyz)))
  • junction_update

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    b = set(a)
    b.intersection_update(xyz)

    b是你的答案

Use intersection or intersection_update

  • intersection :

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    ans = sorted(set(a).intersection(set(xyz)))
    
  • intersection_update:

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    b = set(a)
    b.intersection_update(xyz)
    

    then b is your answer


回答 8

我喜欢Alex的答案,因为过滤器恰好是应用于列表的if,所以如果您想探索给定条件的列表子集,这似乎是最自然的方法

mylist = [1,2,3,4,5]
another_list = [2,3,4]

wanted = lambda x:x in another_list

for x in filter(wanted, mylist):
    print(x)

此方法对于分离关注点很有用,如果条件函数发生变化,则唯一需要摆弄的代码就是函数本身

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

for x in filter(wanted, mylist):
    print(x)

当您不希望列表的成员时,使用generator方法似乎更好,但是可以对所述成员进行修改,这似乎更适合生成器

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

generator = (x**0.5 for x in mylist if wanted(x))

for x in generator:
    print(x)

此外,过滤器可与生成器一起使用,尽管在这种情况下效率不高

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

generator = (x**0.9 for x in mylist)

for x in filter(wanted, generator):
    print(x)

但是,当然,这样写仍然会很好:

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

# for x in filter(wanted, mylist):
for x in mylist if wanted(x):
    print(x)

I liked Alex’s answer, because a filter is exactly an if applied to a list, so if you want to explore a subset of a list given a condition, this seems to be the most natural way

mylist = [1,2,3,4,5]
another_list = [2,3,4]

wanted = lambda x:x in another_list

for x in filter(wanted, mylist):
    print(x)

this method is useful for the separation of concerns, if the condition function changes, the only code to fiddle with is the function itself

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

for x in filter(wanted, mylist):
    print(x)

The generator method seems better when you don’t want members of the list, but a modification of said members, which seems more fit to a generator

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

generator = (x**0.5 for x in mylist if wanted(x))

for x in generator:
    print(x)

Also, filters work with generators, although in this case it isn’t efficient

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

generator = (x**0.9 for x in mylist)

for x in filter(wanted, generator):
    print(x)

But of course, it would still be nice to write like this:

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

# for x in filter(wanted, mylist):
for x in mylist if wanted(x):
    print(x)

回答 9

查找列表a和b的唯一公共元素的简单方法:

a = [1,2,3]
b = [3,6,2]
for both in set(a) & set(b):
    print(both)

A simple way to find unique common elements of lists a and b:

a = [1,2,3]
b = [3,6,2]
for both in set(a) & set(b):
    print(both)

在if语句中初始化的变量的作用域是什么?

问题:在if语句中初始化的变量的作用域是什么?

我是Python的新手,所以这可能是一个简单的范围界定问题。Python文件(模块)中的以下代码使我有些困惑:

if __name__ == '__main__':
    x = 1

print x

在我使用过的其他语言中,此代码将引发异常,因为该x变量是if语句的局部变量,不应在其外部存在。但是此代码将执行并打印1。任何人都可以解释此行为吗?是否在模块中创建的所有变量都是全局的/可用于整个模块?

I’m new to Python, so this is probably a simple scoping question. The following code in a Python file (module) is confusing me slightly:

if __name__ == '__main__':
    x = 1

print x

In other languages I’ve worked in, this code would throw an exception, as the x variable is local to the if statement and should not exist outside of it. But this code executes, and prints 1. Can anyone explain this behavior? Are all variables created in a module global/available to the entire module?


回答 0

Python变量的作用域是分配给它们的最里面的函数,类或模块。控制块(如ifwhile块)不计在内,因此在内分配的变量的if作用域仍限于函数,类或模块。

(由生成器表达式或list / set / dict理解定义的隐式函数与lambda表达式一样进行计数。您不能将赋值语句填充到其中任何一个中,但是lambda参数和for子句目标是隐式赋值。)

Python variables are scoped to the innermost function, class, or module in which they’re assigned. Control blocks like if and while blocks don’t count, so a variable assigned inside an if is still scoped to a function, class, or module.

(Implicit functions defined by a generator expression or list/set/dict comprehension do count, as do lambda expressions. You can’t stuff an assignment statement into any of those, but lambda parameters and for clause targets are implicit assignment.)


回答 1

是的,它们在同一个“本地范围”中,实际上这样的代码在Python中很常见:

if condition:
  x = 'something'
else:
  x = 'something else'

use(x)

请注意,x不会在条件之前声明或初始化它,例如在C或Java中。

换句话说,Python没有块级作用域。不过,请注意以下示例

if False:
    x = 3
print(x)

这显然会引发NameErrorexceptions。

Yes, they’re in the same “local scope”, and actually code like this is common in Python:

if condition:
  x = 'something'
else:
  x = 'something else'

use(x)

Note that x isn’t declared or initialized before the condition, like it would be in C or Java, for example.

In other words, Python does not have block-level scopes. Be careful, though, with examples such as

if False:
    x = 3
print(x)

which would clearly raise a NameError exception.


回答 2

python中的作用域遵循以下顺序:

  • 搜索本地范围

  • 搜索所有封闭函数的范围

  • 搜索全球范围

  • 搜索内置

来源

请注意,if未列出其他循环/分支构造-仅类,函数和模块在Python中提供了作用域,因此,在if块中声明的任何内容都与在该块之外清除的任何内容具有相同的作用域。在编译时不检查变量,这就是为什么其他语言会引发异常的原因。在python中,只要变量在您需要时存在,就不会抛出异常。

Scope in python follows this order:

  • Search the local scope

  • Search the scope of any enclosing functions

  • Search the global scope

  • Search the built-ins

(source)

Notice that if and other looping/branching constructs are not listed – only classes, functions, and modules provide scope in Python, so anything declared in an if block has the same scope as anything decleared outside the block. Variables aren’t checked at compile time, which is why other languages throw an exception. In python, so long as the variable exists at the time you require it, no exception will be thrown.


回答 3

正如Eli所说,Python不需要变量声明。在C中,您会说:

int x;
if(something)
    x = 1;
else
    x = 2;

但在Python中声明是隐式的,因此当您分配给x时,它会自动声明。这是因为Python是动态类型的-它无法在静态类型的语言中工作,因为取决于所使用的路径,可能会在未声明的情况下使用变量。这将在编译时以静态类型的语言捕获,但是允许使用动态类型的语言。

if由于此问题,静态类型的语言仅限于必须在语句之外声明变量的唯一原因。拥抱动态!

As Eli said, Python doesn’t require variable declaration. In C you would say:

int x;
if(something)
    x = 1;
else
    x = 2;

but in Python declaration is implicit, so when you assign to x it is automatically declared. It’s because Python is dynamically typed – it wouldn’t work in a statically typed language, because depending on the path used, a variable might be used without being declared. This would be caught at compile time in a statically typed language, but with a dynamically typed language it’s allowed.

The only reason that a statically typed language is limited to having to declare variables outside of if statements in because of this problem. Embrace the dynamic!


回答 4

与C之类的语言不同,Python变量在它所出现的整个函数(或类,模块)的范围内,而不仅仅是在最内部的“块”中。就像您int x在函数(或类,模块)的顶部声明的一样,只是在Python中不必声明变量。

请注意,x仅在运行时(即,进入print x语句时)检查变量的存在。如果__name__不相等"__main__",则会出现异常:NameError: name 'x' is not defined

Unlike languages such as C, a Python variable is in scope for the whole of the function (or class, or module) where it appears, not just in the innermost “block”. It is as though you declared int x at the top of the function (or class, or module), except that in Python you don’t have to declare variables.

Note that the existence of the variable x is checked only at runtime — that is, when you get to the print x statement. If __name__ didn’t equal "__main__" then you would get an exception: NameError: name 'x' is not defined.


回答 5

是。for范围也是如此。但是当然不起作用。

在您的示例中:如果if语句中的条件为false,x则不会定义。

Yes. It is also true for for scope. But not functions of course.

In your example: if the condition in the if statement is false, x will not be defined though.


回答 6

您是从命令行执行此代码的,因此if条件为true且x已设置。比较:

>>> if False:
    y = 42


>>> y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    y
NameError: name 'y' is not defined

you’re executing this code from command line therefore if conditions is true and x is set. Compare:

>>> if False:
    y = 42


>>> y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    y
NameError: name 'y' is not defined

回答 7

请注意,由于仅在运行时检查Python类型,因此您可以使用如下代码:

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

但是我很难考虑由于类型问题而导致代码无错误运行的其他方式。

And note that since Python types are only checked at runtime you can have code like:

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

But I’m having trouble thinking of other ways in which the code would operate without an error because of type issues.


Python while语句的其他子句

问题:Python while语句的其他子句

我注意到以下代码在Python中是合法的。我的问题是为什么?是否有特定原因?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."

I’ve noticed the following code is legal in Python. My question is why? Is there a specific reason?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."

回答 0

else仅当您的while条件为假时才执行该子句。如果您break超出循环范围,或者引发了异常,则不会执行该异常。

考虑它的一种方法是关于条件的if / else构造:

if condition:
    handle_true()
else:
    handle_false()

与循环构造类似:

while condition:
    handle_true()
else:
    # condition is false now, handle and go on with the rest of the program
    handle_false()

一个示例可能类似于:

while value < threshold:
    if not process_acceptable_value(value):
        # something went wrong, exit the loop; don't pass go, don't collect 200
        break
    value = update(value)
else:
    # value >= threshold; pass go, collect 200
    handle_threshold_reached()

The else clause is only executed when your while condition becomes false. If you break out of the loop, or if an exception is raised, it won’t be executed.

One way to think about it is as an if/else construct with respect to the condition:

if condition:
    handle_true()
else:
    handle_false()

is analogous to the looping construct:

while condition:
    handle_true()
else:
    # condition is false now, handle and go on with the rest of the program
    handle_false()

An example might be along the lines of:

while value < threshold:
    if not process_acceptable_value(value):
        # something went wrong, exit the loop; don't pass go, don't collect 200
        break
    value = update(value)
else:
    # value >= threshold; pass go, collect 200
    handle_threshold_reached()

回答 1

else如果您通过退出循环条件或掉落try块的底部来正常退出一个块,则执行该子句。它执行,如果你break还是return一个块外,或引发异常。它不仅适用于while和for循环,还可以尝试块。

您通常会在通常会提前退出循环的地方找到它,而在循环结束时运行是意外/异常的情况。例如,如果要遍历列表以查找值:

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("

The else clause is executed if you exit a block normally, by hitting the loop condition or falling off the bottom of a try block. It is not executed if you break or return out of a block, or raise an exception. It works for not only while and for loops, but also try blocks.

You typically find it in places where normally you would exit a loop early, and running off the end of the loop is an unexpected/unusual occasion. For example, if you’re looping through a list looking for a value:

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("

回答 2

作为对的答复Is there a specific reason?,这是一个有趣的应用程序:突破了多个循环级别。

它是这样工作的:外循环在结尾处有一个中断,因此只能执行一次。但是,如果内部循环完成(未找到除数),那么它将到达else语句,并且永远不会到达外部中断。这样,内部循环中的中断将打破两个循环,而不仅仅是一个循环。

for k in [2, 3, 5, 7, 11, 13, 17, 25]:
    for m in range(2, 10):
        if k == m:
            continue
        print 'trying %s %% %s' % (k, m)
        if k % m == 0:
            print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
            break
    else:
        continue
    print 'breaking another level of loop'
    break
else:
    print 'no divisor could be found!'

对于whilefor循环else,除非break已使用,否则该语句将在最后执行。

在大多数情况下,有更好的方法可以做到这一点(将其包装到函数中或引发异常),但这是可行的!

In reply to Is there a specific reason?, here is one interesting application: breaking out of multiple levels of looping.

Here is how it works: the outer loop has a break at the end, so it would only be executed once. However, if the inner loop completes (finds no divisor), then it reaches the else statement and the outer break is never reached. This way, a break in the inner loop will break out of both loops, rather than just one.

for k in [2, 3, 5, 7, 11, 13, 17, 25]:
    for m in range(2, 10):
        if k == m:
            continue
        print 'trying %s %% %s' % (k, m)
        if k % m == 0:
            print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
            break
    else:
        continue
    print 'breaking another level of loop'
    break
else:
    print 'no divisor could be found!'

For both while and for loops, the else statement is executed at the end, unless break was used.

In most cases there are better ways to do this (wrapping it into a function or raising an exception), but this works!


回答 3

当while条件评估为false时,将执行else子句。

文档中

只要表达式为真,while语句将用于重复执行:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

这将反复测试表达式,如果为true,则执行第一个套件;否则,将执行第一个套件。如果表达式为假(可能是第一次测试)else,则执行该子句的套件(如果存在),并终止循环。

break在第一个套件中执行的语句将终止循环,而不执行该else子句的套件。continue在第一个套件中执行的语句将跳过套件的其余部分,然后返回测试表达式。

The else-clause is executed when the while-condition evaluates to false.

From the documentation:

The while statement is used for repeated execution as long as an expression is true:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

This repeatedly tests the expression and, if it is true, executes the first suite; if the expression is false (which may be the first time it is tested) the suite of the else clause, if present, is executed and the loop terminates.

A break statement executed in the first suite terminates the loop without executing the else clause’s suite. A continue statement executed in the first suite skips the rest of the suite and goes back to testing the expression.


回答 4

我的回答将集中于何时可以使用while / for-else。

乍一看,使用时似乎没有什么不同

while CONDITION:
    EXPRESSIONS
print 'ELSE'
print 'The next statement'

while CONDITION:
    EXPRESSIONS
else:
    print 'ELSE'
print 'The next statement'

因为该print 'ELSE'语句似乎总是在两种情况下都执行(无论是在while循环结束还是未运行时)。

然后,仅在print 'ELSE'不执行该语句时有所不同。这是break在下面的代码块中while

In [17]: i = 0

In [18]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
else:
    print 'ELSE'
print 'The next statement'
   ....:
0
1
2
The next statement

如果不同于:

In [19]: i = 0

In [20]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
print 'ELSE'
print 'The next statement'
   ....:
0
1
2
ELSE
The next statement

return 不在此类别中,因为它对以上两种情况具有相同的效果。

异常引发也不会引起差异,因为引发异常时,将在异常处理程序(块除外)中执行下一个代码的位置,将不会执行else子句中或while子句之后的代码。

My answer will focus on WHEN we can use while/for-else.

At the first glance, it seems there is no different when using

while CONDITION:
    EXPRESSIONS
print 'ELSE'
print 'The next statement'

and

while CONDITION:
    EXPRESSIONS
else:
    print 'ELSE'
print 'The next statement'

Because the print 'ELSE' statement seems always executed in both cases (both when the while loop finished or not run).

Then, it’s only different when the statement print 'ELSE' will not be executed. It’s when there is a breakinside the code block under while

In [17]: i = 0

In [18]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
else:
    print 'ELSE'
print 'The next statement'
   ....:
0
1
2
The next statement

If differ to:

In [19]: i = 0

In [20]: while i < 5:
    print i
    if i == 2:
        break
    i = i +1
print 'ELSE'
print 'The next statement'
   ....:
0
1
2
ELSE
The next statement

return is not in this category, because it does the same effect for two above cases.

exception raise also does not cause difference, because when it raises, where the next code will be executed is in exception handler (except block), the code in else clause or right after the while clause will not be executed.


回答 5

我知道这是个老问题,但是…

就像Raymond Hettinger所说的那样,应该调用它while/no_break而不是while/else
如果您查看此摘要,我会很容易理解不足。

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
if n == 0:
    print n

现在,我们无需在while循环后检查条件,而是可以将其交换else并摆脱该检查。

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
else:  # read it as "no_break"
    print n

我一直读它是while/no_break为了理解代码,而语法对我来说更有意义。

I know this is old question but…

As Raymond Hettinger said, it should be called while/no_break instead of while/else.
I find it easy to understeand if you look at this snippet.

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
if n == 0:
    print n

Now instead of checking condition after while loop we can swap it with else and get rid of that check.

n = 5
while n > 0:
    print n
    n -= 1
    if n == 2:
        break
else:  # read it as "no_break"
    print n

I always read it as while/no_break to understand the code and that syntax makes much more sense to me.


回答 6

else子句仅在while条件变为false 时执行。

这里有些例子:

示例1:最初条件为假,因此执行else子句

i = 99999999

while i < 5:
    print(i)
    i += 1
else:
    print('this')

输出:

this

例2:同时条件 i < 5从来没有成为因为假i == 3突破的循环,所以else从句未执行。

i = 0

while i < 5:
    print(i)
    if i == 3:
        break
    i += 1
else:
    print('this')

输出:

0
1
2
3

实施例3:而条件 i < 5成为当假i5,所以else从句被执行。

i = 0

while i < 5:
    print(i)
    i += 1
else:
    print('this')

输出:

0
1
2
3
4
this

The else clause is only executed when the while-condition becomes false.

Here are some examples:

Example 1: Initially the condition is false, so else-clause is executed.

i = 99999999

while i < 5:
    print(i)
    i += 1
else:
    print('this')

OUTPUT:

this

Example 2: The while-condition i < 5 never became false because i == 3 breaks the loop, so else-clause was not executed.

i = 0

while i < 5:
    print(i)
    if i == 3:
        break
    i += 1
else:
    print('this')

OUTPUT:

0
1
2
3

Example 3: The while-condition i < 5 became false when i was 5, so else-clause was executed.

i = 0

while i < 5:
    print(i)
    i += 1
else:
    print('this')

OUTPUT:

0
1
2
3
4
this

回答 7

else:仅当while循环不再满足其条件时才执行该语句(在您的示例中,当n != 0false时)。

所以输出是这样的:

5
4
3
2
1
what the...

The else: statement is executed when and only when the while loop no longer meets its condition (in your example, when n != 0 is false).

So the output would be this:

5
4
3
2
1
what the...

回答 8

如果while循环未中断,则执行Else。

我有点想用“跑步者”隐喻来思考它。

“其他”就像越过终点线,与您是从曲目的开头还是结尾开始无关。“其他人”只是,如果你在两者之间的某处破裂执行。

runner_at = 0 # or 10 makes no difference, if unlucky_sector is not 0-10
unlucky_sector = 6
while runner_at < 10:
    print("Runner at: ", runner_at)
    if runner_at == unlucky_sector:
        print("Runner fell and broke his foot. Will not reach finish.")
        break
    runner_at += 1
else:
    print("Runner has finished the race!") # Not executed if runner broke his foot.

主要用例是使用这种脱离嵌套循环的方式,或者仅在循环未在某个地方中断的情况下才想运行某些语句(认为中断是一种不寻常的情况)。

例如,以下是关于如何不使用变量或不尝试/不抓住而跳出内部循环的机制:

for i in [1,2,3]:
    for j in ['a', 'unlucky', 'c']:
        print(i, j)
        if j == 'unlucky':
            break
    else: 
        continue  # Only executed if inner loop didn't break.
    break         # This is only reached if inner loop 'breaked' out since continue didn't run. 

print("Finished")
# 1 a
# 1 b
# Finished

Else is executed if while loop did not break.

I kinda like to think of it with a ‘runner’ metaphor.

The “else” is like crossing the finish line, irrelevant of whether you started at the beginning or end of the track. “else” is only not executed if you break somewhere in between.

runner_at = 0 # or 10 makes no difference, if unlucky_sector is not 0-10
unlucky_sector = 6
while runner_at < 10:
    print("Runner at: ", runner_at)
    if runner_at == unlucky_sector:
        print("Runner fell and broke his foot. Will not reach finish.")
        break
    runner_at += 1
else:
    print("Runner has finished the race!") # Not executed if runner broke his foot.

Main use cases is using this breaking out of nested loops or if you want to run some statements only if loop didn’t break somewhere (think of breaking being an unusual situation).

For example, the following is a mechanism on how to break out of an inner loop without using variables or try/catch:

for i in [1,2,3]:
    for j in ['a', 'unlucky', 'c']:
        print(i, j)
        if j == 'unlucky':
            break
    else: 
        continue  # Only executed if inner loop didn't break.
    break         # This is only reached if inner loop 'breaked' out since continue didn't run. 

print("Finished")
# 1 a
# 1 b
# Finished

回答 9

在Python中更好地使用“ while:else:”构造应该是:如果在“ while”中没有执行循环,则执行“ else”语句。今天的工作方式没有意义,因为您可以使用下面的代码获得相同的结果…

n = 5
while n != 0:
    print n
    n -= 1
print "what the..."

The better use of ‘while: else:’ construction in Python should be if no loop is executed in ‘while’ then the ‘else’ statement is executed. The way it works today doesn’t make sense because you can use the code below with the same results…

n = 5
while n != 0:
    print n
    n -= 1
print "what the..."

回答 10

这对于社交互动很有用。

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")

It is useful for social interaction.

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")

如何编写内联if语句以进行打印?

问题:如何编写内联if语句以进行打印?

我仅在将布尔变量设置为时才需要打印一些内容True。因此,看完这个之后,我尝试了一个简单的示例:

>>> a = 100
>>> b = True
>>> print a if b
  File "<stdin>", line 1
    print a if b
             ^
SyntaxError: invalid syntax  

如果我写的话也是一样print a if b==True

我在这里想念什么?

I need to print some stuff only when a boolean variable is set to True. So, after looking at this, I tried with a simple example:

>>> a = 100
>>> b = True
>>> print a if b
  File "<stdin>", line 1
    print a if b
             ^
SyntaxError: invalid syntax  

Same thing if I write print a if b==True.

What am I missing here?


回答 0

Python不不会有拖尾if 声明

ifPython 有两种:

  1. if 声明:

    if condition: statement
    if condition:
        block
    
  2. if 表达式(在Python 2.5中引入)

    expression_if_true if condition else expression_if_false

请注意,两者print ab = a都是陈述。只有a一部分是表达。所以如果你写

print a if b else 0

它的意思是

print (a if b else 0)

当你写的时候

x = a if b else 0

它的意思是

x = (a if b else 0)

现在,如果没有else子句,它将打印/分配什么?打印/分配仍然存在

请注意,如果您不希望它存在,您总是可以if在一行上编写常规语句,尽管它的可读性较差,并且确实没有理由避免使用两行变体。

Python does not have a trailing if statement.

There are two kinds of if in Python:

  1. if statement:

    if condition: statement
    if condition:
        block
    
  2. if expression (introduced in Python 2.5)

    expression_if_true if condition else expression_if_false
    

And note, that both print a and b = a are statements. Only the a part is an expression. So if you write

print a if b else 0

it means

print (a if b else 0)

and similarly when you write

x = a if b else 0

it means

x = (a if b else 0)

Now what would it print/assign if there was no else clause? The print/assignment is still there.

And note, that if you don’t want it to be there, you can always write the regular if statement on a single line, though it’s less readable and there is really no reason to avoid the two-line variant.


回答 1

内联if-else EXPRESSION必须始终包含else子句,例如:

a = 1 if b else 0

如果您想保持’a’变量值不变-修改旧的’a’值(语法要求中还需要其他):

a = 1 if b else a

这段代码留下一个不变当b转弯是假的。

Inline if-else EXPRESSION must always contain else clause, e.g:

a = 1 if b else 0

If you want to leave your ‘a’ variable value unchanged – assing old ‘a’ value (else is still required by syntax demands):

a = 1 if b else a

This piece of code leaves a unchanged when b turns to be False.


回答 2

‘else’语句是强制性的。您可以执行以下操作:

>>> b = True
>>> a = 1 if b else None
>>> a
1
>>> b = False
>>> a = 1 if b else None
>>> a
>>> 

编辑:

或者,根据您的需要,您可以尝试:

>>> if b: print(a)

The ‘else’ statement is mandatory. You can do stuff like this :

>>> b = True
>>> a = 1 if b else None
>>> a
1
>>> b = False
>>> a = 1 if b else None
>>> a
>>> 

EDIT:

Or, depending of your needs, you may try:

>>> if b: print(a)

回答 3

如果您不想这样做,from __future__ import print_function可以执行以下操作:

a = 100
b = True
print a if b else "",  # Note the comma!
print "see no new line"

哪些打印:

100 see no new line

如果您不反对from __future__ import print_function或使用python 3或更高版本:

from __future__ import print_function
a = False
b = 100
print(b if a else "", end = "")

添加else是您需要进行的唯一更改,以使您的代码在语法上正确无误,您需要条件条件表达式中的else(“如果else阻塞,则行内”)

我没有使用None0与线程中的其他线程一样使用过的None/0原因是,使用会导致程序进入print Noneprint 0处于bis 的情况False

如果您想阅读有关此主题的内容,我提供了指向该功能已添加到Python的补丁程序的发行说明的链接

上面的“模式”与PEP 308中显示的模式非常相似:

这种语法可能看起来很奇怪而且倒退。为什么条件出现在表达式的中间,而不是C的c的前面?x:y?通过将新语法应用于标准库中的模块并查看结果代码的读取方式来检查该决定。在许多使用条件表达式的情况下,一个值似乎是“常见情况”,而一个值是“exceptions情况”,仅在不满足条件的极少数情况下使用。条件语法使此模式更为明显:

内容=((doc +’\ n’)如果文档为其他”)

因此,我认为总体而言,这是一种合理的处理方式,但是您不能凭借以下简单性来参数:

if logging: print data

If you don’t want to from __future__ import print_function you can do the following:

a = 100
b = True
print a if b else "",  # Note the comma!
print "see no new line"

Which prints:

100 see no new line

If you’re not aversed to from __future__ import print_function or are using python 3 or later:

from __future__ import print_function
a = False
b = 100
print(b if a else "", end = "")

Adding the else is the only change you need to make to make your code syntactically correct, you need the else for the conditional expression (the “in line if else blocks”)

The reason I didn’t use None or 0 like others in the thread have used, is because using None/0 would cause the program to print None or print 0 in the cases where b is False.

If you want to read about this topic I’ve included a link to the release notes for the patch that this feature was added to Python.

The ‘pattern’ above is very similar to the pattern shown in PEP 308:

This syntax may seem strange and backwards; why does the condition go in the middle of the expression, and not in the front as in C’s c ? x : y? The decision was checked by applying the new syntax to the modules in the standard library and seeing how the resulting code read. In many cases where a conditional expression is used, one value seems to be the ‘common case’ and one value is an ‘exceptional case’, used only on rarer occasions when the condition isn’t met. The conditional syntax makes this pattern a bit more obvious:

contents = ((doc + ‘\n’) if doc else ”)

So I think overall this is a reasonable way of approching it but you can’t argue with the simplicity of:

if logging: print data

回答 4

从2.5开始,您可以使用C的等价 三元条件运算符,其语法为:

[on_true] if [expression] else [on_false]

所以您的示例很好,但是您只需添加else,例如:

print a if b else ''

Since 2.5 you can use equivalent of C’s ”?:” ternary conditional operator and the syntax is:

[on_true] if [expression] else [on_false]

So your example is fine, but you’ve to simply add else, like:

print a if b else ''

回答 5

您可以使用:

print (1==2 and "only if condition true" or "in case condition is false")

同样,您可以继续以下操作:

print 1==2 and "aa" or ((2==3) and "bb" or "cc")

真实的例子:

>>> print "%d item%s found." % (count, (count>1 and 's' or ''))
1 item found.
>>> count = 2
>>> print "%d item%s found." % (count, (count>1 and 's' or ''))
2 items found.

You can use:

print (1==2 and "only if condition true" or "in case condition is false")

Just as well you can keep going like:

print 1==2 and "aa" or ((2==3) and "bb" or "cc")

Real world example:

>>> print "%d item%s found." % (count, (count>1 and 's' or ''))
1 item found.
>>> count = 2
>>> print "%d item%s found." % (count, (count>1 and 's' or ''))
2 items found.

回答 6

这可以通过字符串格式化来完成。它适用于%表示法以及.format()f字符串(3.6的新功能)

print '%s' % (a if b else "")

要么

print '{}'.format(a if b else "")

要么

print(f'{a if b else ""}')

This can be done with string formatting. It works with the % notation as well as .format() and f-strings (new to 3.6)

print '%s' % (a if b else "")

or

print '{}'.format(a if b else "")

or

print(f'{a if b else ""}')

回答 7

对于您的情况,这可行:

a = b or 0

编辑:这是如何工作的?

在问题中

b = True

所以评估

b or 0

结果是

True

分配给a

如果b == False?b or 0将求值到0将分配给的第二个操作数a

For your case this works:

a = b or 0

Edit: How does this work?

In the question

b = True

So evaluating

b or 0

results in

True

which is assigned to a.

If b == False?, b or 0 would evaluate to the second operand 0 which would be assigned to a.


回答 8

尝试这个 。可能对你有帮助

a=100
b=True

if b:
   print a

Try this . It might help you

a=100
b=True

if b:
   print a

回答 9

您只是太复杂了。

if b:
   print a

You’re simply overcomplicating.

if b:
   print a

回答 10

在以下情况下,您始终需要else内联:

a = 1 if b else 0

但是更简单的方法是a = int(b)

You always need an else in an inline if:

a = 1 if b else 0

But an easier way to do it would be a = int(b).


回答 11

好吧,为什么不简单地写:

if b:
    print a
else:
    print 'b is false'

Well why don’t you simply write:

if b:
    print a
else:
    print 'b is false'

回答 12

嗯,您可以通过列表理解来做到这一点。这只有在您拥有真实范围的情况下才有意义..但是它确实可以做到:

print([a for i in range(0,1) if b])

或仅使用这两个变量:

print([a for a in range(a,a+1) if b])

hmmm, you can do it with a list comprehension. This would only make sense if you had a real range.. but it does do the job:

print([a for i in range(0,1) if b])

or using just those two variables:

print([a for a in range(a,a+1) if b])

为什么python在for和while循环之后使用’else’?

问题:为什么python在for和while循环之后使用’else’?

我了解此构造的工作原理:

for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

但是我不明白为什么else在这里使用它作为关键字,因为这表明有问题的代码仅在for块未完成时才运行,这与它的工作相反!无论我如何考虑,我的大脑都无法从for陈述到else障碍的无缝发展。对我来说,continue还是continuewith更有意义(我正在尝试训练自己这样阅读)。

我想知道Python编码人员是如何在头脑中读取这个结构的(如果愿意,可以大声读出)。也许我缺少使这些代码块更容易理解的东西?

I understand how this construct works:

for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

But I don’t understand why else is used as the keyword here, since it suggests the code in question only runs if the for block does not complete, which is the opposite of what it does! No matter how I think about it, my brain can’t progress seamlessly from the for statement to the else block. To me, continue or continuewith would make more sense (and I’m trying to train myself to read it as such).

I’m wondering how Python coders read this construct in their head (or aloud, if you like). Perhaps I’m missing something that would make such code blocks more easily decipherable?


回答 0

即使是经验丰富的Python程序员,这也是一个奇怪的构造。当与for循环结合使用时,它的基本含义是“在可迭代项中找到某个项目,否则,如果找不到任何项目,则执行…”。如:

found_obj = None
for obj in objects:
    if obj.key == search_key:
        found_obj = obj
        break
else:
    print('No object found.')

但是,只要您看到此构造,一个更好的选择就是将搜索封装在一个函数中:

def find_obj(search_key):
    for obj in objects:
        if obj.key == search_key:
            return obj

或使用列表理解:

matching_objs = [o for o in objects if o.key == search_key]
if matching_objs:
    print('Found {}'.format(matching_objs[0]))
else:
    print('No object found.')

它在语义上不等同于其他两个版本,但是在非性能关键代码中效果很好,在这里,您是否迭代整个列表都没有关系。其他人可能会不同意,但是我个人会避免在生产代码中使用for-else或while-else块。

另请参见[Python-思想] for … else线程的摘要

It’s a strange construct even to seasoned Python coders. When used in conjunction with for-loops it basically means “find some item in the iterable, else if none was found do …”. As in:

found_obj = None
for obj in objects:
    if obj.key == search_key:
        found_obj = obj
        break
else:
    print('No object found.')

But anytime you see this construct, a better alternative is to either encapsulate the search in a function:

def find_obj(search_key):
    for obj in objects:
        if obj.key == search_key:
            return obj

Or use a list comprehension:

matching_objs = [o for o in objects if o.key == search_key]
if matching_objs:
    print('Found {}'.format(matching_objs[0]))
else:
    print('No object found.')

It is not semantically equivalent to the other two versions, but works good enough in non-performance critical code where it doesn’t matter whether you iterate the whole list or not. Others may disagree, but I personally would avoid ever using the for-else or while-else blocks in production code.

See also [Python-ideas] Summary of for…else threads


回答 1

一个常见的构造是运行一个循环,直到找到某些东西,然后打破循环。问题是,如果我跳出循环或循环结束,则需要确定发生哪种情况。一种方法是创建一个标志或存储变量,这将使我进行第二次测试以查看循环是如何退出的。

例如,假设我需要搜索列表并处理每个项目,直到找到标记项目,然后停止处理。如果缺少标志项,则需要引发异常。

使用Python forelse构造

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

将此与不使用此语法糖的方法进行比较:

flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

在第一种情况下,raise紧密绑定到它所使用的for循环。第二,绑定不那么牢固,并且在维护期间可能会引入错误。

A common construct is to run a loop until something is found and then to break out of the loop. The problem is that if I break out of the loop or the loop ends I need to determine which case happened. One method is to create a flag or store variable that will let me do a second test to see how the loop was exited.

For example assume that I need to search through a list and process each item until a flag item is found and then stop processing. If the flag item is missing then an exception needs to be raised.

Using the Python forelse construct you have

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

Compare this to a method that does not use this syntactic sugar:

flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

In the first case the raise is bound tightly to the for loop it works with. In the second the binding is not as strong and errors may be introduced during maintenance.


回答 2

Raymond Hettinger的精彩演讲名为“ 将代码转换为美丽的惯用Python”,在其中他简要介绍了该for ... else构造的历史。相关部分是“在循环中区分多个出口点”,从15:50开始,持续大约三分钟。这里是要点:

  • for ... else结构是由Donald Knuth设计的,用于替换某些GOTO用例。
  • 重用该else关键字是有道理的,因为“这是Knuth所使用的,那时人们知道,所有[ for语句]都嵌入了an ifGOTOunder,而他们期望使用else;”。
  • 事后看来,它应该被称为“不间断”(或可能称为“不间断”),这样就不会造成混淆。*

因此,如果问题是“他们为什么不更改此关键字?” 那么Cat Plus Plus可能给出了最准确的答案 –在这一点上,它对现有代码的破坏性太大,无法实用。但是,如果您真正要问的问题是为什么else首先要重用,那么显然在当时看来是个好主意。

就个人而言,我喜欢# no break在线注释的妥协之else处,因为它们一眼就可能被误认为属于循环内。相当清晰简洁。Bjorn在回答结束时链接的摘要中简要提及了该选项:

为了完整起见,我应该提到的是,语法稍有变化,想要这种语法的程序员现在可以使用它:

for item in sequence:
    process(item)
else:  # no break
    suite

*视频那部分的奖励语录:“就像我们调用lambda makefunction一样,没人会问’lambda做什么?’”

There’s an excellent presentation by Raymond Hettinger, titled Transforming Code into Beautiful, Idiomatic Python, in which he briefly addresses the history of the for ... else construct. The relevant section is “Distinguishing multiple exit points in loops” starting at 15:50 and continuing for about three minutes. Here are the high points:

  • The for ... else construct was devised by Donald Knuth as a replacement for certain GOTO use cases;
  • Reusing the else keyword made sense because “it’s what Knuth used, and people knew, at that time, all [for statements] had embedded an if and GOTO underneath, and they expected the else;”
  • In hindsight, it should have been called “no break” (or possibly “nobreak”), and then it wouldn’t be confusing.*

So, if the question is, “Why don’t they change this keyword?” then Cat Plus Plus probably gave the most accurate answer – at this point, it would be too destructive to existing code to be practical. But if the question you’re really asking is why else was reused in the first place, well, apparently it seemed like a good idea at the time.

Personally, I like the compromise of commenting # no break in-line wherever the else could be mistaken, at a glance, as belonging inside the loop. It’s reasonably clear and concise. This option gets a brief mention in the summary that Bjorn linked at the end of his answer:

For completeness, I should mention that with a slight change in syntax, programmers who want this syntax can have it right now:

for item in sequence:
    process(item)
else:  # no break
    suite

* Bonus quote from that part of the video: “Just like if we called lambda makefunction, nobody would ask, ‘What does lambda do?'”


回答 3

因为他们不想在语言中引入新的关键字。每个人都窃取一个标识符并引起向后兼容性问题,因此通常是最后的选择。

Because they didn’t want to introduce a new keyword to the language. Each one steals an identifier and causes backwards compatibility problems, so it’s usually a last resort.


回答 4

简单起见,您可以这样想:

  • 如果breakfor循环中遇到命令,else则不会调用该部件。
  • 如果breakfor循环中未遇到该命令,else则将调用该部件。

换句话说,如果for循环迭代未被破坏breakelse则将调用该部分。

To make it simple, you can think of it like that;

  • If it encounters the break command in the for loop, the else part will not be called.
  • If it does not encounter the break command in the for loop, the else part will be called.

In other words, if for loop iteration is not “broken” with break, the else part will be called.


回答 5

我发现“了解” for / else所做的事情,最重要的是,何时使用它,最简单的方法是专注于break语句跳转到的位置。For / else构造是单个块。中断从块中跳出,因此跳过“ else”子句。如果else子句的内容仅位于for子句之后,则它将永远不会被跳过,因此必须通过将其放在if中来提供等效的逻辑。之前已经说过,但用这些话还不够,所以可能会对其他人有所帮助。尝试运行以下代码片段。为了澄清,我全心全意地赞成“不间断”的评论。

for a in range(3):
    print(a)
    if a==4: # change value to force break or not
        break
else: #no break  +10 for whoever thought of this decoration
    print('for completed OK')

print('statement after for loop')

The easiest way I found to ‘get’ what the for/else did, and more importantly, when to use it, was to concentrate on where the break statement jumps to. The For/else construct is a single block. The break jumps out of the block, and so jumps ‘over’ the else clause. If the contents of the else clause simply followed the for clause, it would never be jumped over, and so the equivalent logic would have to be provided by putting it in an if. This has been said before, but not quite in these words, so it may help somebody else. Try running the following code fragment. I’m wholeheartedly in favour of the ‘no break’ comment for clarity.

for a in range(3):
    print(a)
    if a==4: # change value to force break or not
        break
else: #no break  +10 for whoever thought of this decoration
    print('for completed OK')

print('statement after for loop')

回答 6

我认为文档对其他方面有很好的解释 ,请继续

[…]当循环通过用尽列表而终止(使用for)或条件变为假(使用while)时执行,但在循环由break语句终止时则不执行。”

来源:Python 2文档:控制流教程

I think documentation has a great explanation of else, continue

[…] it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.”

Source: Python 2 docs: Tutorial on control flow


回答 7

我读到类似:

如果仍然有运行循环的条件,则执行其他操作,否则执行其他操作。

I read it something like:

If still on the conditions to run the loop, do stuff, else do something else.


回答 8

由于已经回答了很多技术方面的问题,因此我的评论仅与产生此回收关键字的混乱有关。

作为Python是一种非常有说服力的编程语言,关键字的滥用更为臭名昭著。该else关键字恰如其分地描述决策树的流程的一部分,“如果你不能做到这一点,(否则)做到这一点。” 它是用我们自己的语言暗示的

相反,将此关键字与whileand for语句一起使用会引起混淆。原因是,我们作为程序员的职业使我们知道该else语句位于决策树之内。它的逻辑范围,一个有条件地返回要遵循的路径的包装器。同时,循环语句具有比喻明确的目标。在流程的不断迭代之后,可以达到目标。

if / else 指明可以遵循的道路。循环遵循一条路径,直到“目标”完成

问题是这个else词清楚地定义了条件中的最后一个选项。这个词的语义由Python和人类语言共享。但是,人类语言中的else词永远不会用来表示某人或某事在完成某件事后将要采取的行动。如果在完成过程中出现问题(更像是休息),则将使用它语句)。

最后,关键字将保留在Python中。显然,这是错误的,当每个程序员尝试提出一个故事来理解其用法(如某种助记符设备)时,这一点就更加清楚。如果他们选择了关键字,我会很喜欢的then。我相信这个关键字非常适合迭代流程,即循环后的收益

这类似于某些孩子在按照每个步骤组装玩具后所遇到的情况:那么,爸爸是什么?

Since the technical part has been pretty much answered, my comment is just in relation with the confusion that produce this recycled keyword.

Being Python a very eloquent programming language, the misuse of a keyword is more notorious. The else keyword perfectly describes part of the flow of a decision tree, “if you can’t do this, (else) do that”. It’s implied in our own language.

Instead, using this keyword with while and for statements creates confusion. The reason, our career as programmers has taught us that the else statement resides within a decision tree; its logical scope, a wrapper that conditionally return a path to follow. Meanwhile, loop statements have a figurative explicit goal to reach something. The goal is met after continuous iterations of a process.

if / else indicate a path to follow. Loops follow a path until the “goal” is completed.

The issue is that else is a word that clearly define the last option in a condition. The semantics of the word are both shared by Python and Human Language. But the else word in Human Language is never used to indicate the actions someone or something will take after something is completed. It will be used if, in the process of completing it, an issue rises (more like a break statement).

At the end, the keyword will remain in Python. It’s clear it was mistake, clearer when every programmer tries to come up with a story to understand its usage like some mnemonic device. I’d have loved if they have chosen instead the keyword then. I believe that this keyword fits perfectly in that iterative flow, the payoff after the loop.

It resembles that situation that some child has after following every step in assembling a toy: And THEN what Dad?


回答 9

我将其读为“当iterable完全耗尽时,执行将在完成完成后继续执行下for一条语句,否则将执行else子句。” 因此,当迭代被中断时break,将不会执行。

I read it like “When the iterable is exhausted completely, and the execution is about to proceed to the next statement after finishing the for, the else clause will be executed.” Thus, when the iteration is broken by break, this will not be executed.


回答 10

我同意,它更像是“不是[[条件]打破休息条件]”。

我知道这是一个老话题,但是我现在正在研究相同的问题,而且我不确定有人以我理解的方式抓住了这个问题的答案。

对我来说,有三种“读取” elsein For... elseWhile... else语句的方法,所有这些方法都是等效的:

  1. else == if the loop completes normally (without a break or error)
  2. else == if the loop does not encounter a break
  3. else == else not (condition raising break) (大概有这种情况,否则您将不会循环)

因此,从本质上讲,循环中的“ else”实际上是一个“ elif …”,其中“ …”是(1)不间断,相当于(2)NOT [引起中断的条件]。

我认为关键是else没有’break’就没有意义,因此a for...else包括:

for:
    do stuff
    conditional break # implied by else
else not break:
    do more stuff

因此,for...else循环的基本元素如下,您将以普通英语阅读它们:

for:
    do stuff
    condition:
        break
else: # read as "else not break" or "else not condition"
    do more stuff

正如其他张贴者所说的那样,当您能够找到循环要查找的内容时,通常会出现中断,因此else:变成“如果未找到目标项目该怎么办”。

您还可以一起使用异常处理,中断和for循环。

for x in range(0,3):
    print("x: {}".format(x))
    if x == 2:
        try:
            raise AssertionError("ASSERTION ERROR: x is {}".format(x))
        except:
            print(AssertionError("ASSERTION ERROR: x is {}".format(x)))
            break
else:
    print("X loop complete without error")

结果

x: 0
x: 1
x: 2
ASSERTION ERROR: x is 2
----------
# loop not completed (hit break), so else didn't run

一个简单的例子,打破休息。

for y in range(0,3):
    print("y: {}".format(y))
    if y == 2: # will be executed
        print("BREAK: y is {}\n----------".format(y))
        break
else: # not executed because break is hit
    print("y_loop completed without break----------\n")

结果

y: 0
y: 1
y: 2
BREAK: y is 2
----------
# loop not completed (hit break), so else didn't run

一个简单的示例,其中没有中断,没有引发中断的条件,也没有遇到错误。

for z in range(0,3):
     print("z: {}".format(z))
     if z == 4: # will not be executed
         print("BREAK: z is {}\n".format(y))
         break
     if z == 4: # will not be executed
         raise AssertionError("ASSERTION ERROR: x is {}".format(x))
else:
     print("z_loop complete without break or error\n----------\n")

结果

z: 0
z: 1
z: 2
z_loop complete without break or error
----------

I agree, it’s more like an ‘elif not [condition(s) raising break]’.

I know this is an old thread, but I am looking into the same question right now, and I’m not sure anyone has captured the answer to this question in the way I understand it.

For me, there are three ways of “reading” the else in For... else or While... else statements, all of which are equivalent, are:

  1. else == if the loop completes normally (without a break or error)
  2. else == if the loop does not encounter a break
  3. else == else not (condition raising break) (presumably there is such a condition, or you wouldn’t have a loop)

So, essentially, the “else” in a loop is really an “elif …” where ‘…’ is (1) no break, which is equivalent to (2) NOT [condition(s) raising break].

I think the key is that the else is pointless without the ‘break’, so a for...else includes:

for:
    do stuff
    conditional break # implied by else
else not break:
    do more stuff

So, essential elements of a for...else loop are as follows, and you would read them in plainer English as:

for:
    do stuff
    condition:
        break
else: # read as "else not break" or "else not condition"
    do more stuff

As the other posters have said, a break is generally raised when you are able to locate what your loop is looking for, so the else: becomes “what to do if target item not located”.

Example

You can also use exception handling, breaks, and for loops all together.

for x in range(0,3):
    print("x: {}".format(x))
    if x == 2:
        try:
            raise AssertionError("ASSERTION ERROR: x is {}".format(x))
        except:
            print(AssertionError("ASSERTION ERROR: x is {}".format(x)))
            break
else:
    print("X loop complete without error")

Result

x: 0
x: 1
x: 2
ASSERTION ERROR: x is 2
----------
# loop not completed (hit break), so else didn't run

Example

Simple example with a break being hit.

for y in range(0,3):
    print("y: {}".format(y))
    if y == 2: # will be executed
        print("BREAK: y is {}\n----------".format(y))
        break
else: # not executed because break is hit
    print("y_loop completed without break----------\n")

Result

y: 0
y: 1
y: 2
BREAK: y is 2
----------
# loop not completed (hit break), so else didn't run

Example

Simple example where there no break, no condition raising a break, and no error are encountered.

for z in range(0,3):
     print("z: {}".format(z))
     if z == 4: # will not be executed
         print("BREAK: z is {}\n".format(y))
         break
     if z == 4: # will not be executed
         raise AssertionError("ASSERTION ERROR: x is {}".format(x))
else:
     print("z_loop complete without break or error\n----------\n")

Result

z: 0
z: 1
z: 2
z_loop complete without break or error
----------

回答 11

else这里,关键字可能会引起混淆,正如许多人指出的那样nobreaknotbreak是比较合适的。

为了for ... else ...逻辑上理解,请将其与try...except...else而不是进行比较if...else...,大多数python程序员都熟悉以下代码:

try:
    do_something()
except:
    print("Error happened.") # The try block threw an exception
else:
    print("Everything is find.") # The try block does things just find.

同样,可以认为break是一种特殊的Exception

for x in iterable:
    do_something(x)
except break:
    pass # Implied by Python's loop semantics
else:
    print('no break encountered')  # No break statement was encountered

区别是python隐含的except break,您无法将其写出,因此它变为:

for x in iterable:
    do_something(x)
else:
    print('no break encountered')  # No break statement was encountered

是的,我知道这种比较可能很困难并且很累,但是确实可以澄清这种混淆。

The else keyword can be confusing here, and as many people have pointed out, something like nobreak, notbreak is more appropriate.

In order to understand for ... else ... logically, compare it with try...except...else, not if...else..., most of python programmers are familiar with the following code:

try:
    do_something()
except:
    print("Error happened.") # The try block threw an exception
else:
    print("Everything is find.") # The try block does things just find.

Similarly, think of break as a special kind of Exception:

for x in iterable:
    do_something(x)
except break:
    pass # Implied by Python's loop semantics
else:
    print('no break encountered')  # No break statement was encountered

The difference is python implies except break and you can not write it out, so it becomes:

for x in iterable:
    do_something(x)
else:
    print('no break encountered')  # No break statement was encountered

Yes, I know this comparison can be difficult and tiresome, but it does clarify the confusion.


回答 12

elsefor不中断循环时,将执行语句块中的代码。

for x in xrange(1,5):
    if x == 5:
        print 'find 5'
        break
else:
    print 'can not find 5!'
#can not find 5!

文档:中断并继续执行语句,否则循环中的子句

循环语句可以包含else子句;当循环通过用尽列表而终止(使用for)或条件变为假(使用while)时,将执行此命令,但当循环由break语句终止时,则不会执行该命令。以下循环示例搜索质数:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(是的,这是正确的代码。仔细观察:else子句属于for循环,而不是if语句。)

与循环一起使用时,else子句与try语句的else子句比if语句具有更多的共同点:try语句的else子句在没有异常发生时运行,而循环的else子句在没有中断时发生运行。有关try语句和异常的更多信息,请参见处理异常。

也从C借用的continue语句继续循环的下一个迭代:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

Codes in else statement block will be executed when the for loop was not be broke.

for x in xrange(1,5):
    if x == 5:
        print 'find 5'
        break
else:
    print 'can not find 5!'
#can not find 5!

From the docs: break and continue Statements, and else Clauses on Loops

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)

When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions.

The continue statement, also borrowed from C, continues with the next iteration of the loop:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

回答 13

这是一种我上面没有见过其他人提到的思考方式:

首先,请记住,for循环基本上只是while循环周围的语法糖。例如循环

for item in sequence:
    do_something(item)

可以(近似)重写为

item = None
while sequence.hasnext():
    item = sequence.next()
    do_something(item)

其次,请记住,while循环基本上只是重复的if块!您始终可以将while循环读为“如果满足此条件,则执行主体,然后返回并再次检查”。

因此,while / else完全有道理:它与if / else完全相同,具有附加的循环功能,直到条件变为false为止,而不仅仅是检查条件一次。

然后for / else也很有意义:由于所有for循环只是while循环之上的语法糖,您只需要弄清楚底层while循环的隐式条件是什么,然后else对应于何时条件变为False。

Here’s a way to think about it that I haven’t seen anyone else mention above:

First, remember that for-loops are basically just syntactic sugar around while-loops. For example, the loop

for item in sequence:
    do_something(item)

can be rewritten (approximately) as

item = None
while sequence.hasnext():
    item = sequence.next()
    do_something(item)

Second, remember that while-loops are basically just repeated if-blocks! You can always read a while-loop as “if this condition is true, execute the body, then come back and check again”.

So while/else makes perfect sense: It’s the exact same structure as if/else, with the added functionality of looping until the condition becomes false instead of just checking the condition once.

And then for/else makes perfect sense too: because all for-loops are just syntactic sugar on top of while-loops, you just need to figure out what the underlying while-loop’s implicit conditional is, and then the else corresponds to when that condition becomes False.


回答 14

很好的答案是:

  • 可以解释历史,并且
  • 这样可以正确引用,以简化您的翻译/理解。

我在这里的注释来自Donald Knuth曾经说过的(抱歉无法找到参考),其中有一个while-else与if-else不能区分的构造,即(在Python中):

x = 2
while x > 3:
    print("foo")
    break
else:
    print("boo")

具有与以下相同的流量(不包括低级别差异):

x = 2
if x > 3:
    print("foo")
else:
    print("boo")

关键是,if-else可以被视为while-else的语法糖,而while-else break在其if块的末尾具有隐含的含义。相反的含义是,while循环是对的扩展if,这是更常见的(只是重复/循环条件检查),因为if通常在之前进行过讲授while。但是,这是不正确的,因为这意味着每次条件为false时else都会执行while-else块。

为了简化您的理解,请考虑以下方式:

如果不使用breakreturn等,则循环仅在条件不再为真时结束,并且在这种情况下,else块也将执行一次。如果是Python for,则必须考虑C型for循环(有条件)或将其转换为while

另一个注意事项:

过早breakreturn等内部循环,使不可能的条件,成为虚假的,因为执行跃升循环出来,而条件是真实的,它永远不会回来再检查一遍。

Great answers are:

  • this which explain the history, and
  • this gives the right citation to ease yours translation/understanding.

My note here comes from what Donald Knuth once said (sorry can’t find reference) that there is a construct where while-else is indistinguishable from if-else, namely (in Python):

x = 2
while x > 3:
    print("foo")
    break
else:
    print("boo")

has the same flow (excluding low level differences) as:

x = 2
if x > 3:
    print("foo")
else:
    print("boo")

The point is that if-else can be considered as syntactic sugar for while-else which has implicit break at the end of its if block. The opposite implication, that while loop is extension to if, is more common (it’s just repeated/looped conditional check), because if is often taught before while. However that isn’t true because that would mean else block in while-else would be executed each time when condition is false.

To ease your understanding think of it that way:

Without break, return, etc., loop ends only when condition is no longer true and in such case else block will also execute once. In case of Python for you must consider C-style for loops (with conditions) or translate them to while.

Another note:

Premature break, return, etc. inside loop makes impossible for condition to become false because execution jumped out of the loop while condition was true and it would never come back to check it again.


回答 15

您可以将其想像为 else其余内容或其他内容中未在循环中完成的。

You could think of it like, else as in the rest of the stuff, or the other stuff, that wasn’t done in the loop.


回答 16

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

“ else”在这里非常简单,只是意味着

1,“如果for clause完成”

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
if "for clause is completed":
    print("Completed successfully")

想要写“ for子句已完成”这样的长语句,所以要引入“ else”。

else 这本质上是一种假设。

2,但是,怎么样 for clause is not run at all

In [331]: for i in range(0):
     ...:     print(i)
     ...: 
     ...:     if i == 9:
     ...:         print("Too big - I'm giving up!")
     ...:         break
     ...: else:
     ...:     print("Completed successfully")
     ...:     
Completed successfully

因此,完全可以说是逻辑组合:

if "for clause is completed" or "not run at all":
     do else stuff

或这样说:

if "for clause is not partially run":
    do else stuff

或者这样:

if "for clause not encounter a break":
    do else stuff
for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

“else” here is crazily simple, just mean

1, “if for clause is completed”

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
if "for clause is completed":
    print("Completed successfully")

It’s wielding to write such long statements as “for clause is completed”, so they introduce “else”.

else here is a if in its nature.

2, However, How about for clause is not run at all

In [331]: for i in range(0):
     ...:     print(i)
     ...: 
     ...:     if i == 9:
     ...:         print("Too big - I'm giving up!")
     ...:         break
     ...: else:
     ...:     print("Completed successfully")
     ...:     
Completed successfully

So it’s completely statement is logic combination:

if "for clause is completed" or "not run at all":
     do else stuff

or put it this way:

if "for clause is not partially run":
    do else stuff

or this way:

if "for clause not encounter a break":
    do else stuff

回答 17

除了搜索之外,这是另一个惯用例。假设您要等待条件为真,例如,要在远程服务器上打开端口以及一些超时。然后,您可以利用这样的while...else构造:

import socket
import time

sock = socket.socket()
timeout = time.time() + 15
while time.time() < timeout:
    if sock.connect_ex(('127.0.0.1', 80)) is 0:
        print('Port is open now!')
        break
    print('Still waiting...')
else:
    raise TimeoutError()

Here’s another idiomatic use case besides searching. Let’s say you wanted to wait for a condition to be true, e.g. a port to be open on a remote server, along with some timeout. Then you could utilize a while...else construct like so:

import socket
import time

sock = socket.socket()
timeout = time.time() + 15
while time.time() < timeout:
    if sock.connect_ex(('127.0.0.1', 80)) is 0:
        print('Port is open now!')
        break
    print('Still waiting...')
else:
    raise TimeoutError()

回答 18

我只是想自己重新理解它。我发现以下帮助!

•将else视为与if循环内部配对(而不是与for)配对-如果满足条件,则打破循环,否则执行此操作-除非它else与多个ifs 配对!
•如果根本if不满意,请执行else
•多重ifS可实际上也被认为是ifelifs ^!

I was just trying to make sense of it again myself. I found that the following helps!

• Think of the else as being paired with the if inside the loop (instead of with the for) – if condition is met then break the loop, else do this – except it’s one else paired with multiple ifs!
• If no ifs were satisfied at all, then do the else.
• The multiple ifs can also actually be thought of as ifelifs!


回答 19

我认为结构为(如果)在其他B,以及(如果)-else是一个特殊的if-else粗略。可能有助于了解其他

A和B最多执行一次,这与if-else结构相同。

for(if)可以认为是特殊的if,它会循环执行以尝试满足if条件。一旦满足if条件,则A 中断否则,B.

I consider the structure as for (if) A else B, and for(if)-else is a special if-else, roughly. It may help to understand else.

A and B is executed at most once, which is the same as if-else structure.

for(if) can be considered as a special if, which does a loop to try to meet the if condition. Once the if condition is met, A and break; Else, B.


回答 20

Python在for和while循环之后使用else循环,因此,如果没有任何内容适用于循环,则会发生其他情况。例如:

test = 3
while test == 4:
     print("Hello")
else:
     print("Hi")

输出将是一遍又一遍的“ Hi”(如果我是对的)。

Python uses an else after for and while loops so that if nothing applies to the loop, something else happens. For example:

test = 3
while test == 4:
     print("Hello")
else:
     print("Hi")

The output would be ‘Hi’ over and over again (if I’m correct).


在if语句中,Python等效于&&(逻辑与)

问题:在if语句中,Python等效于&&(逻辑与)

这是我的代码:

def front_back(a, b):
  # +++your code here+++
  if len(a) % 2 == 0 && len(b) % 2 == 0:
    return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
  else:
    #todo! Not yet done. :P
  return

我在IF条件中遇到错误。
我究竟做错了什么?

Here’s my code:

def front_back(a, b):
  # +++your code here+++
  if len(a) % 2 == 0 && len(b) % 2 == 0:
    return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
  else:
    #todo! Not yet done. :P
  return

I’m getting an error in the IF conditional.
What am I doing wrong?


回答 0

您可能想要and而不是&&

You would want and instead of &&.


回答 1

Python使用andor条件。

if foo == 'abc' and bar == 'bac' or zoo == '123':
  # do something

Python uses and and or conditionals.

i.e.

if foo == 'abc' and bar == 'bac' or zoo == '123':
  # do something

回答 2

我在IF条件中遇到错误。我究竟做错了什么?

得到a的原因SyntaxError&&Python中没有运算符。同样||!并且不是有效的 Python运算符。

您可能从其他语言中了解到的某些运算符在Python中使用不同的名称。逻辑运算符&&||实际上被称为andor。同样,逻辑否定运算符!称为not

所以你可以这样写:

if len(a) % 2 == 0 and len(b) % 2 == 0:

甚至:

if not (len(a) % 2 or len(b) % 2):

一些其他信息(可能会派上用场):

我在此表中总结了运算符“等效项”:

+------------------------------+---------------------+
|  Operator (other languages)  |  Operator (Python)  |
+==============================+=====================+
|              &&              |         and         |
+------------------------------+---------------------+
|              ||              |         or          |
+------------------------------+---------------------+
|              !               |         not         |
+------------------------------+---------------------+

另请参阅Python文档:6.11。布尔运算

除了逻辑运算符外,Python还具有按位/二进制运算符:

+--------------------+--------------------+
|  Logical operator  |  Bitwise operator  |
+====================+====================+
|        and         |         &          |
+--------------------+--------------------+
|         or         |         |          |
+--------------------+--------------------+

Python中没有按位取反(只是按位逆运算符~-但这并不等效于not)。

另见6.6。一元算术和按位/二进制运算6.7。二进制算术运算

逻辑运算符(像许多其他语言一样)具有使它们短路的优点。这意味着,如果第一个操作数已经定义了结果,则根本不会对第二个运算符求值。

为了说明这一点,我使用了一个简单地使用值的函数,将其打印并再次返回。方便查看由于print语句而实际评估的内容:

>>> def print_and_return(value):
...     print(value)
...     return value

>>> res = print_and_return(False) and print_and_return(True)
False

如您所见,仅执行了一个print语句,因此Python甚至没有查看正确的操作数。

对于二进制运算符,情况并非如此。那些总是评估两个操作数:

>>> res = print_and_return(False) & print_and_return(True);
False
True

但是,如果第一个操作数不够用,那么,当然会计算第二个运算符:

>>> res = print_and_return(True) and print_and_return(False);
True
False

总结一下,这是另一个表:

+-----------------+-------------------------+
|   Expression    |  Right side evaluated?  |
+=================+=========================+
| `True` and ...  |           Yes           |
+-----------------+-------------------------+
| `False` and ... |           No            |
+-----------------+-------------------------+
|  `True` or ...  |           No            |
+-----------------+-------------------------+
| `False` or ...  |           Yes           |
+-----------------+-------------------------+

TrueFalse代表什么bool(left-hand-side)回报,他们不必是TrueFalse,他们只需要返回TrueFalsebool被要求他们(1)。

因此,在Pseudo-Code(!)中,andand or函数的工作方式如下:

def and(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return evaluate(expr2)
    else:
        return left

def or(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return left
    else:
        return evaluate(expr2)

请注意,这是伪代码,而不是Python代码。在Python中,您无法创建称为and或的函数,or因为这些是关键字。另外,您永远不要使用“评估”或if bool(...)

自定义自己的类的行为

这隐含bool调用可用于自定义您的类的行为有andornot

为了说明如何进行自定义,我使用该类来再次print跟踪正在发生的事情:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        print('__bool__ called on {!r}'.format(self))
        return bool(self.value)

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

因此,让我们看看与这些运算符结合使用该类会发生什么:

>>> if Test(True) and Test(False):
...     pass
__bool__ called on Test(True)
__bool__ called on Test(False)

>>> if Test(False) or Test(False):
...     pass
__bool__ called on Test(False)
__bool__ called on Test(False)

>>> if not Test(True):
...     pass
__bool__ called on Test(True)

如果您没有__bool__方法,Python还将检查对象是否具有__len__方法,以及它是否返回大于零的值。如果您创建了序列容器,可能会很有用。

另请参阅4.1。真值测试

NumPy数组和子类

可能超出了原始问题的范围,但是如果您要处理NumPy数组或子类(如Pandas Series或DataFrames),则隐式bool调用将引发可怕的问题ValueError

>>> import numpy as np
>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> import pandas as pd
>>> s = pd.Series([1,2,3])
>>> bool(s)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> s and s
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

在这些情况下,您可以使用NumPy中的逻辑和函数,该逻辑和函数执行逐个元素and(或or):

>>> np.logical_and(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([False, False,  True, False])
>>> np.logical_or(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([ True, False,  True,  True])

如果您只处理布尔数组,则还可以将二进制运算符与NumPy一起使用,它们确实会执行按元素进行比较(也可以是二进制)的比较:

>>> np.array([False,False,True,True]) & np.array([True, False, True, False])
array([False, False,  True, False])
>>> np.array([False,False,True,True]) | np.array([True, False, True, False])
array([ True, False,  True,  True])

(1)

bool对操作数调用必须返回True或者False是不完全正确的。它只是第一个需要在其__bool__方法中返回布尔值的操作数:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        return self.value

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

>>> x = Test(10) and Test(10)
TypeError: __bool__ should return bool, returned int
>>> x1 = Test(True) and Test(10)
>>> x2 = Test(False) and Test(10)

这是因为,and如果第一个操作数求和False,则实际返回第一个操作数;如果求和,True则返回第二个操作数:

>>> x1
Test(10)
>>> x2
Test(False)

同样,or但相反:

>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)

但是,如果您在if语句中使用它们,if也会隐式调用bool结果。因此,这些要点可能与您无关。

I’m getting an error in the IF conditional. What am I doing wrong?

There reason that you get a SyntaxError is that there is no && operator in Python. Likewise || and ! are not valid Python operators.

Some of the operators you may know from other languages have a different name in Python. The logical operators && and || are actually called and and or. Likewise the logical negation operator ! is called not.

So you could just write:

if len(a) % 2 == 0 and len(b) % 2 == 0:

or even:

if not (len(a) % 2 or len(b) % 2):

Some additional information (that might come in handy):

I summarized the operator “equivalents” in this table:

+------------------------------+---------------------+
|  Operator (other languages)  |  Operator (Python)  |
+==============================+=====================+
|              &&              |         and         |
+------------------------------+---------------------+
|              ||              |         or          |
+------------------------------+---------------------+
|              !               |         not         |
+------------------------------+---------------------+

See also Python documentation: 6.11. Boolean operations.

Besides the logical operators Python also has bitwise/binary operators:

+--------------------+--------------------+
|  Logical operator  |  Bitwise operator  |
+====================+====================+
|        and         |         &          |
+--------------------+--------------------+
|         or         |         |          |
+--------------------+--------------------+

There is no bitwise negation in Python (just the bitwise inverse operator ~ – but that is not equivalent to not).

See also 6.6. Unary arithmetic and bitwise/binary operations and 6.7. Binary arithmetic operations.

The logical operators (like in many other languages) have the advantage that these are short-circuited. That means if the first operand already defines the result, then the second operator isn’t evaluated at all.

To show this I use a function that simply takes a value, prints it and returns it again. This is handy to see what is actually evaluated because of the print statements:

>>> def print_and_return(value):
...     print(value)
...     return value

>>> res = print_and_return(False) and print_and_return(True)
False

As you can see only one print statement is executed, so Python really didn’t even look at the right operand.

This is not the case for the binary operators. Those always evaluate both operands:

>>> res = print_and_return(False) & print_and_return(True);
False
True

But if the first operand isn’t enough then, of course, the second operator is evaluated:

>>> res = print_and_return(True) and print_and_return(False);
True
False

To summarize this here is another Table:

+-----------------+-------------------------+
|   Expression    |  Right side evaluated?  |
+=================+=========================+
| `True` and ...  |           Yes           |
+-----------------+-------------------------+
| `False` and ... |           No            |
+-----------------+-------------------------+
|  `True` or ...  |           No            |
+-----------------+-------------------------+
| `False` or ...  |           Yes           |
+-----------------+-------------------------+

The True and False represent what bool(left-hand-side) returns, they don’t have to be True or False, they just need to return True or False when bool is called on them (1).

So in Pseudo-Code(!) the and and or functions work like these:

def and(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return evaluate(expr2)
    else:
        return left

def or(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return left
    else:
        return evaluate(expr2)

Note that this is pseudo-code not Python code. In Python you cannot create functions called and or or because these are keywords. Also you should never use “evaluate” or if bool(...).

Customizing the behavior of your own classes

This implicit bool call can be used to customize how your classes behave with and, or and not.

To show how this can be customized I use this class which again prints something to track what is happening:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        print('__bool__ called on {!r}'.format(self))
        return bool(self.value)

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

So let’s see what happens with that class in combination with these operators:

>>> if Test(True) and Test(False):
...     pass
__bool__ called on Test(True)
__bool__ called on Test(False)

>>> if Test(False) or Test(False):
...     pass
__bool__ called on Test(False)
__bool__ called on Test(False)

>>> if not Test(True):
...     pass
__bool__ called on Test(True)

If you don’t have a __bool__ method then Python also checks if the object has a __len__ method and if it returns a value greater than zero. That might be useful to know in case you create a sequence container.

See also 4.1. Truth Value Testing.

NumPy arrays and subclasses

Probably a bit beyond the scope of the original question but in case you’re dealing with NumPy arrays or subclasses (like Pandas Series or DataFrames) then the implicit bool call will raise the dreaded ValueError:

>>> import numpy as np
>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> import pandas as pd
>>> s = pd.Series([1,2,3])
>>> bool(s)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> s and s
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

In these cases you can use the logical and function from NumPy which performs an element-wise and (or or):

>>> np.logical_and(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([False, False,  True, False])
>>> np.logical_or(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([ True, False,  True,  True])

If you’re dealing just with boolean arrays you could also use the binary operators with NumPy, these do perform element-wise (but also binary) comparisons:

>>> np.array([False,False,True,True]) & np.array([True, False, True, False])
array([False, False,  True, False])
>>> np.array([False,False,True,True]) | np.array([True, False, True, False])
array([ True, False,  True,  True])

(1)

That the bool call on the operands has to return True or False isn’t completely correct. It’s just the first operand that needs to return a boolean in it’s __bool__ method:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        return self.value

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

>>> x = Test(10) and Test(10)
TypeError: __bool__ should return bool, returned int
>>> x1 = Test(True) and Test(10)
>>> x2 = Test(False) and Test(10)

That’s because and actually returns the first operand if the first operand evaluates to False and if it evaluates to True then it returns the second operand:

>>> x1
Test(10)
>>> x2
Test(False)

Similarly for or but just the other way around:

>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)

However if you use them in an if statement the if will also implicitly call bool on the result. So these finer points may not be relevant for you.


回答 3

两条评论:

  • 在Python中使用andor进行逻辑操作。
  • 使用4个空格而不是2缩进。您稍后将感谢自己,因为您的代码看起来与其他人的代码几乎相同。有关更多详细信息,请参见PEP 8

Two comments:

  • Use and and or for logical operations in Python.
  • Use 4 spaces to indent instead of 2. You will thank yourself later because your code will look pretty much the same as everyone else’s code. See PEP 8 for more details.

回答 4

您可以使用andor执行类似C,C ++的逻辑操作。就像字面上的andis &&oris一样||


看看这个有趣的例子,

假设您要使用Python构建Logic Gate:

def AND(a,b):
    return (a and b) #using and operator

def OR(a,b):
    return (a or b)  #using or operator

现在尝试调用给他们:

print AND(False, False)
print OR(True, False)

这将输出:

False
True

希望这可以帮助!

You use and and or to perform logical operations like in C, C++. Like literally and is && and or is ||.


Take a look at this fun example,

Say you want to build Logic Gates in Python:

def AND(a,b):
    return (a and b) #using and operator

def OR(a,b):
    return (a or b)  #using or operator

Now try calling them:

print AND(False, False)
print OR(True, False)

This will output:

False
True

Hope this helps!


回答 5

我提出了一个纯粹的数学解决方案:

def front_back(a, b):
  return a[:(len(a)+1)//2]+b[:(len(b)+1)//2]+a[(len(a)+1)//2:]+b[(len(b)+1)//2:]

I went with a purlely mathematical solution:

def front_back(a, b):
  return a[:(len(a)+1)//2]+b[:(len(b)+1)//2]+a[(len(a)+1)//2:]+b[(len(b)+1)//2:]

回答 6

可能这不是执行此任务的最佳代码,但是可以正常工作-

def front_back(a, b):

 if len(a) % 2 == 0 and len(b) % 2 == 0:
    print a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):]

 elif len(a) % 2 == 1 and len(b) % 2 == 0:
    print a[:(len(a)/2)+1] + b[:(len(b)/2)] + a[(len(a)/2)+1:] + b[(len(b)/2):] 

 elif len(a) % 2 == 0 and len(b) % 2 == 1:
     print a[:(len(a)/2)] + b[:(len(b)/2)+1] + a[(len(a)/2):] + b[(len(b)/2)+1:] 

 else :
     print a[:(len(a)/2)+1] + b[:(len(b)/2)+1] + a[(len(a)/2)+1:] + b[(len(b)/2)+1:]

Probably this is not best code for this task, but is working –

def front_back(a, b):

 if len(a) % 2 == 0 and len(b) % 2 == 0:
    print a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):]

 elif len(a) % 2 == 1 and len(b) % 2 == 0:
    print a[:(len(a)/2)+1] + b[:(len(b)/2)] + a[(len(a)/2)+1:] + b[(len(b)/2):] 

 elif len(a) % 2 == 0 and len(b) % 2 == 1:
     print a[:(len(a)/2)] + b[:(len(b)/2)+1] + a[(len(a)/2):] + b[(len(b)/2)+1:] 

 else :
     print a[:(len(a)/2)+1] + b[:(len(b)/2)+1] + a[(len(a)/2)+1:] + b[(len(b)/2)+1:]

回答 7

一个&(而不是double &&)就足够了,或者作为最高答案建议您可以使用’and’。我也在大熊猫中发现了

cities['Is wide and has saint name'] = (cities['Population'] > 1000000) 
& cities['City name'].apply(lambda name: name.startswith('San'))

如果我们将“&”替换为“ and”,则将无法使用。

A single & (not double &&) is enough or as the top answer suggests you can use ‘and’. I also found this in pandas

cities['Is wide and has saint name'] = (cities['Population'] > 1000000) 
& cities['City name'].apply(lambda name: name.startswith('San'))

if we replace the “&” with “and”, it won’t work.


回答 8

也许用&代替%可以更快并保持可读性

其他测试奇数/奇数

x是偶数?x%2 == 0

x是奇数?不是x%2 == 0

也许按位和1更清楚

x是奇数?x&1

x是偶数?不是x&1(不奇怪)

def front_back(a, b):
    # +++your code here+++
    if not len(a) & 1 and not len(b) & 1:
        return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
    else:
        #todo! Not yet done. :P
    return

maybe with & instead % is more fast and mantain readibility

other tests even/odd

x is even ? x % 2 == 0

x is odd ? not x % 2 == 0

maybe is more clear with bitwise and 1

x is odd ? x & 1

x is even ? not x & 1 (not odd)

def front_back(a, b):
    # +++your code here+++
    if not len(a) & 1 and not len(b) & 1:
        return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
    else:
        #todo! Not yet done. :P
    return

回答 9

有条件地使用“和”。在Jupyter Notebook导入时,我经常使用此功能:

def find_local_py_scripts():
    import os # does not cost if already imported
    for entry in os.scandir('.'):
        # find files ending with .py
        if entry.is_file() and entry.name.endswith(".py") :
            print("- ", entry.name)
find_local_py_scripts()

-  googlenet_custom_layers.py
-  GoogLeNet_Inception_v1.py

Use of “and” in conditional. I often use this when importing in Jupyter Notebook:

def find_local_py_scripts():
    import os # does not cost if already imported
    for entry in os.scandir('.'):
        # find files ending with .py
        if entry.is_file() and entry.name.endswith(".py") :
            print("- ", entry.name)
find_local_py_scripts()

-  googlenet_custom_layers.py
-  GoogLeNet_Inception_v1.py

在“ if”语句中设置多行条件的样式?[关闭]

问题:在“ if”语句中设置多行条件的样式?[关闭]

有时我将ifs中的长条条件分解为几行。最明显的方法是:

  if (cond1 == 'val1' and cond2 == 'val2' and
      cond3 == 'val3' and cond4 == 'val4'):
      do_something

在视觉上不是很吸引人,因为动作与条件融为一体。但是,这是使用正确的4个空格的Python缩进的自然方法。

目前,我正在使用:

  if (    cond1 == 'val1' and cond2 == 'val2' and
          cond3 == 'val3' and cond4 == 'val4'):
      do_something

但这不是很漂亮。:-)

您能推荐一种替代方法吗?

Sometimes I break long conditions in ifs onto several lines. The most obvious way to do this is:

  if (cond1 == 'val1' and cond2 == 'val2' and
      cond3 == 'val3' and cond4 == 'val4'):
      do_something

Isn’t very very appealing visually, because the action blends with the conditions. However, it is the natural way using correct Python indentation of 4 spaces.

For the moment I’m using:

  if (    cond1 == 'val1' and cond2 == 'val2' and
          cond3 == 'val3' and cond4 == 'val4'):
      do_something

But this isn’t very pretty. :-)

Can you recommend an alternative way?


回答 0

您不需要在第二条条件行上使用4个空格。可能使用:

if (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

另外,不要忘记空白比您想象的更灵活:

if (   
       cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something
if    (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

两者都相当丑陋。

也许丢了括号(尽管《风格指南》不鼓励这样做)?

if cond1 == 'val1' and cond2 == 'val2' and \
   cond3 == 'val3' and cond4 == 'val4':
    do_something

这至少使您与众不同。

甚至:

if cond1 == 'val1' and cond2 == 'val2' and \
                       cond3 == 'val3' and \
                       cond4 == 'val4':
    do_something

我想我更喜欢:

if cond1 == 'val1' and \
   cond2 == 'val2' and \
   cond3 == 'val3' and \
   cond4 == 'val4':
    do_something

这是《样式指南》,(自2010年起)建议使用括号。

You don’t need to use 4 spaces on your second conditional line. Maybe use:

if (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

Also, don’t forget the whitespace is more flexible than you might think:

if (   
       cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something
if    (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

Both of those are fairly ugly though.

Maybe lose the brackets (the Style Guide discourages this though)?

if cond1 == 'val1' and cond2 == 'val2' and \
   cond3 == 'val3' and cond4 == 'val4':
    do_something

This at least gives you some differentiation.

Or even:

if cond1 == 'val1' and cond2 == 'val2' and \
                       cond3 == 'val3' and \
                       cond4 == 'val4':
    do_something

I think I prefer:

if cond1 == 'val1' and \
   cond2 == 'val2' and \
   cond3 == 'val3' and \
   cond4 == 'val4':
    do_something

Here’s the Style Guide, which (since 2010) recommends using brackets.


回答 1

在简并的情况下,我采用了以下内容:简而言之,其为AND或OR。

if all( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

if any( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

它可以刮掉几个字符,并清楚表明该条件没有任何微妙之处。

I’ve resorted to the following in the degenerate case where it’s simply AND’s or OR’s.

if all( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

if any( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

It shaves a few characters and makes it clear that there’s no subtlety to the condition.


回答 2

有人必须在这里提倡使用垂直空格!:)

if (     cond1 == val1
     and cond2 == val2
     and cond3 == val3
   ):
    do_stuff()

这使得每个条件都清晰可见。它还可以更清晰地表达更复杂的条件:

if (    cond1 == val1
     or 
        (     cond2_1 == val2_1
          and cond2_2 >= val2_2
          and cond2_3 != bad2_3
        )
   ):
    do_more_stuff()

是的,为了清楚起见,我们将权衡一些垂直房地产。IMO值得。

Someone has to champion use of vertical whitespace here! :)

if (     cond1 == val1
     and cond2 == val2
     and cond3 == val3
   ):
    do_stuff()

This makes each condition clearly visible. It also allows cleaner expression of more complex conditions:

if (    cond1 == val1
     or 
        (     cond2_1 == val2_1
          and cond2_2 >= val2_2
          and cond2_3 != bad2_3
        )
   ):
    do_more_stuff()

Yes, we’re trading off a bit of vertical real estate for clarity. Well worth it IMO.


回答 3

当我有一个非常大的if条件时,我更喜欢这种风格:

if (
    expr1
    and (expr2 or expr3)
    and hasattr(thingy1, '__eq__')
    or status=="HappyTimes"
):
    do_stuff()
else:
    do_other_stuff()

I prefer this style when I have a terribly large if-condition:

if (
    expr1
    and (expr2 or expr3)
    and hasattr(thingy1, '__eq__')
    or status=="HappyTimes"
):
    do_stuff()
else:
    do_other_stuff()

回答 4

这是我非常个人的看法:(在我看来)长时间条件是一种代码气味,建议将其重构为布尔返回函数/方法。例如:

def is_action__required(...):
    return (cond1 == 'val1' and cond2 == 'val2'
            and cond3 == 'val3' and cond4 == 'val4')

现在,如果我找到一种使多行条件看起来不错的方法,那么我可能会发现自己对满足这些条件感到满意,而无需进行重构。

另一方面,让它们扰乱我的审美意识可以促进重构。

因此,我的结论是,多个线路条件看起来很丑陋,这是避免它们的诱因。

Here’s my very personal take: long conditions are (in my view) a code smell that suggests refactoring into a boolean-returning function/method. For example:

def is_action__required(...):
    return (cond1 == 'val1' and cond2 == 'val2'
            and cond3 == 'val3' and cond4 == 'val4')

Now, if I found a way to make multi-line conditions look good, I would probably find myself content with having them and skip the refactoring.

On the other hand, having them perturb my aesthetic sense acts as an incentive for refactoring.

My conclusion, therefore, is that multiple line conditions should look ugly and this is an incentive to avoid them.


回答 5

这并没有太大改善,但是…

allCondsAreOK = (cond1 == 'val1' and cond2 == 'val2' and
                 cond3 == 'val3' and cond4 == 'val4')

if allCondsAreOK:
   do_something

This doesn’t improve so much but…

allCondsAreOK = (cond1 == 'val1' and cond2 == 'val2' and
                 cond3 == 'val3' and cond4 == 'val4')

if allCondsAreOK:
   do_something

回答 6

我建议将and关键字移至第二行,并将包含条件的所有行缩进,而不是四个空格:

if (cond1 == 'val1' and cond2 == 'val2'
  and cond3 == 'val3' and cond4 == 'val4'):
    do_something

这正是我在代码中解决此问题的方式。将关键字作为该行中的第一个单词使该条件更具可读性,并且减少空格的数量进一步将条件与动作区分开。

I suggest moving the and keyword to the second line and indenting all lines containing conditions with two spaces instead of four:

if (cond1 == 'val1' and cond2 == 'val2'
  and cond3 == 'val3' and cond4 == 'val4'):
    do_something

This is exactly how I solve this problem in my code. Having a keyword as the first word in the line makes the condition a lot more readable, and reducing the number of spaces further distinguishes condition from action.


回答 7

似乎值得引用PEP 0008(Python的官方样式指南),因为它以适度的长度评论了这个问题:

当- if语句的条件部分足够长以至于需要将其写成多行时,值得注意的是,两个字符关键字(即if),一个空格和一个左括号的组合会产生自然的4-多行条件的后续行的空格缩进。这可能与嵌套在if-statement中的缩进代码套件产生视觉冲突,该缩进代码套件自然也会缩进4个空格。对于如何(或是否)在视觉上进一步将这些条件行与if-statement 内的嵌套套件区分开,此PEP没有明确的位置。在这种情况下,可接受的选项包括但不限于:

# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

注意上面引用中的“不限于”;除了在样式指南中建议的方法外,在此问题的其他答案中建议的一些方法也是可以接受的。

It seems worth quoting PEP 0008 (Python’s official style guide), since it comments upon this issue at modest length:

When the conditional part of an if -statement is long enough to require that it be written across multiple lines, it’s worth noting that the combination of a two character keyword (i.e. if ), plus a single space, plus an opening parenthesis creates a natural 4-space indent for the subsequent lines of the multiline conditional. This can produce a visual conflict with the indented suite of code nested inside the if -statement, which would also naturally be indented to 4 spaces. This PEP takes no explicit position on how (or whether) to further visually distinguish such conditional lines from the nested suite inside the if -statement. Acceptable options in this situation include, but are not limited to:

# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

Note the “not limited to” in the quote above; besides the approaches suggested in the style guide, some of the ones suggested in other answers to this question are acceptable too.


回答 8

这就是我的工作,请记住“ all”和“ any”接受迭代,因此我将一个长条件放在列表中,然后让“ all”完成工作。

condition = [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4']

if all(condition):
   do_something

Here’s what I do, remember that “all” and “any” accepts an iterable, so I just put a long condition in a list and let “all” do the work.

condition = [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4']

if all(condition):
   do_something

回答 9

我很惊讶没有看到我的首选解决方案,

if (cond1 == 'val1' and cond2 == 'val2'
    and cond3 == 'val3' and cond4 == 'val4'):
    do_something

由于and是一个关键字,因此我的编辑器将其突出显示,并且看起来与其下方的do_something完全不同。

I’m surprised not to see my preferred solution,

if (cond1 == 'val1' and cond2 == 'val2'
    and cond3 == 'val3' and cond4 == 'val4'):
    do_something

Since and is a keyword, it gets highlighted by my editor, and looks sufficiently different from the do_something below it.


回答 10

加上@krawyoti所说的话…长时间的气味会散发出来,因为它们难以阅读且难以理解。使用函数或变量可使代码更清晰。在Python中,我更喜欢使用垂直空间,将括号括起来,并将逻辑运算符放在每行的开头,以使表达式看起来不像“浮动”。

conditions_met = (
    cond1 == 'val1' 
    and cond2 == 'val2' 
    and cond3 == 'val3' 
    and cond4 == 'val4'
    )
if conditions_met:
    do_something

如果需要多次评估条件(例如在while循环中),则最好使用局部函数。

Adding to what @krawyoti said… Long conditions smell because they are difficult to read and difficult to understand. Using a function or a variable makes the code clearer. In Python, I prefer to use vertical space, enclose parenthesis, and place the logical operators at the beginning of each line so the expressions don’t look like “floating”.

conditions_met = (
    cond1 == 'val1' 
    and cond2 == 'val2' 
    and cond3 == 'val3' 
    and cond4 == 'val4'
    )
if conditions_met:
    do_something

If the conditions need to be evaluated more than once, as in a while loop, then using a local function is best.


回答 11

就个人而言,我喜欢在长if语句中添加含义。我将不得不在代码中进行搜索以找到合适的示例,但这是我想到的第一个示例:假设我碰巧遇到了一些古怪的逻辑,我想根据许多变量来显示特定页面。

英语:“如果登录的用户不是管理员教师,而是普通教师,而不是学生本身…”

if not user.isAdmin() and user.isTeacher() and not user.isStudent():
    doSomething()

当然,这看起来不错,但是如果需要大量阅读,请阅读这些内容。我们如何将逻辑分配给有意义的标签。“标签”实际上是变量名:

displayTeacherPanel = not user.isAdmin() and user.isTeacher() and not user.isStudent()
if displayTeacherPanel:
    showTeacherPanel()

这看起来似乎很愚蠢,但是您可能还有另一种情况,您仅在显示教师面板或默认情况下用户有权访问其他特定面板时才要显示其他项目:

if displayTeacherPanel or user.canSeeSpecialPanel():
    showSpecialPanel()

尝试在不使用变量来存储和标记逻辑的情况下编写上述条件,不仅会得到非常混乱,难以理解的逻辑语句,而且还会重复自己。尽管有合理的exceptions情况,但请记住:不要重复自己(DRY)。

Personally, I like to add meaning to long if-statements. I would have to search through code to find an appropriate example, but here’s the first example that comes to mind: let’s say I happen to run into some quirky logic where I want to display a certain page depending on many variables.

English: “If the logged-in user is NOT an administrator teacher, but is just a regular teacher, and is not a student themselves…”

if not user.isAdmin() and user.isTeacher() and not user.isStudent():
    doSomething()

Sure this might look fine, but reading those if statements is a lot of work. How about we assign the logic to label that makes sense. The “label” is actually the variable name:

displayTeacherPanel = not user.isAdmin() and user.isTeacher() and not user.isStudent()
if displayTeacherPanel:
    showTeacherPanel()

This may seem silly, but you might have yet another condition where you ONLY want to display another item if, and only if, you’re displaying the teacher panel OR if the user has access to that other specific panel by default:

if displayTeacherPanel or user.canSeeSpecialPanel():
    showSpecialPanel()

Try writing the above condition without using variables to store and label your logic, and not only do you end up with a very messy, hard-to-read logical statement, but you also just repeated yourself. While there are reasonable exceptions, remember: Don’t Repeat Yourself (DRY).


回答 12

“ all”和“ any”对于相同类型案例的许多条件都很好。但是他们总是评估所有条件。如本例所示:

def c1():
    print " Executed c1"
    return False
def c2():
    print " Executed c2"
    return False


print "simple and (aborts early!)"
if c1() and c2():
    pass

print

print "all (executes all :( )"
if all((c1(),c2())):
    pass

print

“all” and “any” are nice for the many conditions of same type case. BUT they always evaluates all conditions. As shown in this example:

def c1():
    print " Executed c1"
    return False
def c2():
    print " Executed c2"
    return False


print "simple and (aborts early!)"
if c1() and c2():
    pass

print

print "all (executes all :( )"
if all((c1(),c2())):
    pass

print

回答 13

(我对标识符进行了小幅修改,因为固定宽度的名称不代表真实代码-至少不代表我遇到的真实代码-这将掩盖示例的可读性。)

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4"):
    do_something

这对于“ and”和“ or”非常有效(重要的是它们排在第二行),但对于其他较长条件则远不如此。幸运的是,前者似乎是更常见的情况,而后者通常很容易用一个临时变量重写。(通常并不难,但是在重写时保留“和” /“或”的短路可能很困难或不太明显/可读性。)

由于我从您的博客文章中找到了有关C ++的问题,因此我将介绍我的C ++样式是相同的:

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4") {
    do_something
}

(I’ve lightly modified the identifiers as fixed-width names aren’t representative of real code – at least not real code that I encounter – and will belie an example’s readability.)

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4"):
    do_something

This works well for “and” and “or” (it’s important that they’re first on the second line), but much less so for other long conditions. Fortunately, the former seem to be the more common case while the latter are often easily rewritten with a temporary variable. (It’s usually not hard, but it can be difficult or much less obvious/readable to preserve the short-circuiting of “and”/”or” when rewriting.)

Since I found this question from your blog post about C++, I’ll include that my C++ style is identical:

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4") {
    do_something
}

回答 14

简单明了,还通过了pep8检查:

if (
    cond1 and
    cond2
):
    print("Hello World!")

近年来,我一直偏爱alland any函数,因为我很少将And和Or混合使用,因此效果很好,并且具有生成器理解失败的额外优势:

if all([
    cond1,
    cond2,
]):
    print("Hello World!")

只记得传递一个可迭代的值!传递N参数是不正确的。

注意:any就像很多or比较,all就像很多and比较。


这与生成器理解很好地结合在一起,例如:

# Check if every string in a list contains a substring:
my_list = [
    'a substring is like a string', 
    'another substring'
]

if all('substring' in item for item in my_list):
   print("Hello World!")

# or

if all(
    'substring' in item
    for item in my_list
):
    print("Hello World!")

更多信息:生成器理解

Plain and simple, also passes pep8 checks:

if (
    cond1 and
    cond2
):
    print("Hello World!")

In recent times I have been preferring the all and any functions, since I rarely mix And and Or comparisons this works well, and has the additional advantage of Failing Early with generators comprehension:

if all([
    cond1,
    cond2,
]):
    print("Hello World!")

Just remember to pass in a single iterable! Passing in N-arguments is not correct.

Note: any is like many or comparisons, all is like many and comparisons.


This combines nicely with generator comprehensions, for example:

# Check if every string in a list contains a substring:
my_list = [
    'a substring is like a string', 
    'another substring'
]

if all('substring' in item for item in my_list):
   print("Hello World!")

# or

if all(
    'substring' in item
    for item in my_list
):
    print("Hello World!")

More on: generator comprehension


回答 15

如果我们仅在条件和身体之间插入一条额外的空白行,而其余部分以规范的方式进行,该怎么办?

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):

    do_something

ps我总是使用制表符,而不是空格。我无法微调…

What if we only insert an additional blank line between the condition and the body and do the rest in the canonical way?

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):

    do_something

p.s. I always use tabs, not spaces; I cannot fine-tune…


回答 16

我通常要做的是:

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something

这样,右括号和冒号在视觉上标志着我们病情的结束。

What I usually do is:

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something

this way the closing brace and colon visually mark the end of our condition.


回答 17

也为if语句提供多条件的所有受访者与所提出的问题一样丑陋。您不能通过做同样的事情来解决此问题。

甚至PEP 0008的答案也是令人反感的。

这是一种更具可读性的方法

condition = random.randint(0, 100) # to demonstrate
anti_conditions = [42, 67, 12]
if condition not in anti_conditions:
    pass

要我吃我的话吗?说服我,您需要多条件,并且我会逐字打印出来,并出于娱乐目的而食用。

All respondents that also provide multi-conditionals for the if statement is just as ugly as the problem presented. You don’t solve this problem by doing the same thing..

Even the PEP 0008 answer is repulsive.

Here is a far more readable approach

condition = random.randint(0, 100) # to demonstrate
anti_conditions = [42, 67, 12]
if condition not in anti_conditions:
    pass

Want me to eat my words? Convince me you need multi-conditionals and I’ll literally print this and eat it for your amusement.


回答 18

我认为@zkanda的解决方案稍作改动就可以了。如果您在各自的列表中有条件和值,则可以使用列表推导进行比较,这将使添加条件/值对的过程更加通用。

conditions = [1, 2, 3, 4]
values = [1, 2, 3, 4]
if all([c==v for c, v in zip(conditions, values)]):
    # do something

如果我确实想对这样的语句进行硬编码,出于可读性考虑,我会这样写:

if (condition1==value1) and (condition2==value2) and \
   (condition3==value3) and (condition4==value4):

并与iand操作员一起提出另一个解决方案:

proceed = True
for c, v in zip(conditions, values):
    proceed &= c==v

if proceed:
    # do something

I think @zkanda’s solution would be good with a minor twist. If you had your conditions and values in their own respective lists, you could use a list comprehension to do the comparison, which would make things a bit more general for adding condition/value pairs.

conditions = [1, 2, 3, 4]
values = [1, 2, 3, 4]
if all([c==v for c, v in zip(conditions, values)]):
    # do something

If I did want to hard-code a statement like this, I would write it like this for legibility:

if (condition1==value1) and (condition2==value2) and \
   (condition3==value3) and (condition4==value4):

And just to throw another solution out there with an iand operator:

proceed = True
for c, v in zip(conditions, values):
    proceed &= c==v

if proceed:
    # do something

回答 19

出于完整性考虑,仅提供了一些其他随机想法。如果它们对您有用,请使用它们。否则,您最好尝试其他方法。

您也可以使用字典来做到这一点:

>>> x = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> y = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> x == y
True

这个选项比较复杂,但是您可能还会发现它有用:

class Klass(object):
    def __init__(self, some_vars):
        #initialize conditions here
    def __nonzero__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
                self.cond3 == 'val3' and self.cond4 == 'val4')

foo = Klass()
if foo:
    print "foo is true!"
else:
    print "foo is false!"

邓诺(Dunno)是否适合您,但这是您可以考虑的另一种选择。这是另一种方式:

class Klass(object):
    def __init__(self):
        #initialize conditions here
    def __eq__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
               self.cond3 == 'val3' and self.cond4 == 'val4')

x = Klass(some_values)
y = Klass(some_other_values)
if x == y:
    print 'x == y'
else:
    print 'x!=y'

我还没有测试过最后两个,但是如果您想使用这些概念,那么它们的概念应该足以让您开始工作。

(从记录来看,如果这只是一次性的事情,那么使用最初介绍的方法可能会更好。如果在很多地方进行比较,这些方法可能会增强可读性,从而使您不会因为它们有点hacky而感到难过。)

Just a few other random ideas for completeness’s sake. If they work for you, use them. Otherwise, you’re probably better off trying something else.

You could also do this with a dictionary:

>>> x = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> y = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> x == y
True

This option is more complicated, but you may also find it useful:

class Klass(object):
    def __init__(self, some_vars):
        #initialize conditions here
    def __nonzero__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
                self.cond3 == 'val3' and self.cond4 == 'val4')

foo = Klass()
if foo:
    print "foo is true!"
else:
    print "foo is false!"

Dunno if that works for you, but it’s another option to consider. Here’s one more way:

class Klass(object):
    def __init__(self):
        #initialize conditions here
    def __eq__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
               self.cond3 == 'val3' and self.cond4 == 'val4')

x = Klass(some_values)
y = Klass(some_other_values)
if x == y:
    print 'x == y'
else:
    print 'x!=y'

The last two I haven’t tested, but the concepts should be enough to get you going if that’s what you want to go with.

(And for the record, if this is just a one time thing, you’re probably just better off using the method you presented at first. If you’re doing the comparison in lots of places, these methods may enhance readability enough to make you not feel so bad about the fact that they are kind of hacky.)


回答 20

我一直在努力寻找一种合适的方法来做到这一点,所以我只是想出了一个主意(不是灵丹妙药,因为这主要是一个品味问题)。

if bool(condition1 and
        condition2 and
        ...
        conditionN):
    foo()
    bar()

与我见过的其他解决方案相比,我发现此解决方案有一些优点,即,您恰好获得了额外的4个缩进空间(布尔),允许所有条件垂直排列,并且if语句的主体可以缩进一种清晰的方式 这也保留了对布尔运算符进行短路评估的好处,但是当然会增加基本上不执行任何操作的函数调用的开销。您可能会(有效地)争辩说,可以在此处使用任何返回其参数的函数而不是bool,但是就像我说的那样,这只是一个主意,最终是一个品味问题。

有趣的是,当我写这篇文章并思考“问题”时,我想到了另一个想法,它消除了函数调用的开销。为什么不通过使用额外的圆括号来表明我们将要输入复杂的条件?再说2个,相对于if语句的主体,给子条件一个2的空格缩进。例:

if (((foo and
      bar and
      frob and
      ninja_bear))):
    do_stuff()

我之所以喜欢这样,是因为当您看着它时,头上的铃铛立即响起,说:“嘿,这是一件复杂的事情!” 。是的,我知道括号并不能帮助提高可读性,但是这些条件应该很少出现,并且当它们出现时,您无论如何都要停下来仔细阅读它们(因为它们很复杂))。

无论如何,只有两个我在这里没有看到的建议。希望这可以帮助某人:)

I’ve been struggling to find a decent way to do this as well, so I just came up with an idea (not a silver bullet, since this is mainly a matter of taste).

if bool(condition1 and
        condition2 and
        ...
        conditionN):
    foo()
    bar()

I find a few merits in this solution compared to others I’ve seen, namely, you get exactly an extra 4 spaces of indentation (bool), allowing all conditions to line up vertically, and the body of the if statement can be indented in a clear(ish) way. This also keeps the benefits of short-circuit evaluation of boolean operators, but of course adds the overhead of a function call that basically does nothing. You could argue (validly) that any function returning its argument could be used here instead of bool, but like I said, it’s just an idea and it’s ultimately a matter of taste.

Funny enough, as I was writing this and thinking about the “problem”, I came up with yet another idea, which removes the overhead of a function call. Why not indicate that we’re about to enter a complex condition by using extra pairs of parentheses? Say, 2 more, to give a nice 2 space indent of the sub-conditions relative to the body of the if statement. Example:

if (((foo and
      bar and
      frob and
      ninja_bear))):
    do_stuff()

I kind of like this because when you look at it, a bell immediatelly rings in your head saying “hey, there’s a complex thing going on here!”. Yes, I know that parentheses don’t help readability, but these conditions should appear rarely enough, and when they do show up, you are going to have to stop and read them carefuly anyway (because they’re complex).

Anyway, just two more proposals that I haven’t seen here. Hope this helps someone :)


回答 21

您可以将其分为两行

total = cond1 == 'val' and cond2 == 'val2' and cond3 == 'val3' and cond4 == val4
if total:
    do_something()

甚至一次添加一个条件。这样,至少可以将混乱与混乱分开if

You could split it into two lines

total = cond1 == 'val' and cond2 == 'val2' and cond3 == 'val3' and cond4 == val4
if total:
    do_something()

Or even add on one condition at a time. That way, at least it separates the clutter from the if.


回答 22

我知道这个线程很旧,但是我有一些Python 2.7代码,PyCharm(4.5)仍然抱怨这种情况:

if foo is not None:
    if (cond1 == 'val1' and cond2 == 'val2' and
        cond3 == 'val3' and cond4 == 'val4'):
            # some comment about do_something
            do_something

即使PEP8警告“带有与下一个逻辑行相同的缩进的可视缩进行”,实际代码也完全可以吗?这不是“缩进过度”吗?

…有时候我希望Python会咬住子弹,并且用花括号将其消失。我不知道这些年来由于偶然的错误压痕而意外引入了多少个错误…

I know this thread is old, but I have some Python 2.7 code and PyCharm (4.5) still complains about this case:

if foo is not None:
    if (cond1 == 'val1' and cond2 == 'val2' and
        cond3 == 'val3' and cond4 == 'val4'):
            # some comment about do_something
            do_something

Even with the PEP8 warning “visually indented line with same indent as next logical line”, the actual code is completely OK? It’s not “over-indenting?”

…there are times I wish Python would’ve bit the bullet and just gone with curly braces. I wonder how many bugs have been accidentally introduced over the years due to accidental mis-indentation…


回答 23

将您的条件打包到一个列表中,然后再做。喜欢:

if False not in Conditions:
    do_something

Pack your conditions into a list, then do smth. like:

if False not in Conditions:
    do_something

回答 24

我发现当我的条件很长时,我通常会有一个简短的代码主体。在这种情况下,我只是将身体缩进两次,因此:

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):
        do_something

I find that when I have long conditions, I often have a short code body. In that case, I just double-indent the body, thus:

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):
        do_something

回答 25

  if cond1 == 'val1' and \
     cond2 == 'val2' and \
     cond3 == 'val3' and \
     cond4 == 'val4':
      do_something

或者,如果更清楚:

  if cond1 == 'val1'\
     and cond2 == 'val2'\
     and cond3 == 'val3'\
     and cond4 == 'val4':
      do_something

在这种情况下,缩进没有理由应为4的倍数,例如,请参见“与开孔定界符对齐”:

http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation

  if cond1 == 'val1' and \
     cond2 == 'val2' and \
     cond3 == 'val3' and \
     cond4 == 'val4':
      do_something

or if this is clearer:

  if cond1 == 'val1'\
     and cond2 == 'val2'\
     and cond3 == 'val3'\
     and cond4 == 'val4':
      do_something

There is no reason indent should be a multiple of 4 in this case, e.g. see “Aligned with opening delimiter”:

http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation


回答 26

这是另一种方法:

cond_list = ['cond1 == "val1"','cond2=="val2"','cond3=="val3"','cond4=="val4"']
if all([eval(i) for i in cond_list]):
 do something

这也使您可以轻松地添加另一个条件,而无需更改if语句,只需将另一个条件附加到列表即可:

cond_list.append('cond5=="val5"')

Here’s another approach:

cond_list = ['cond1 == "val1"','cond2=="val2"','cond3=="val3"','cond4=="val4"']
if all([eval(i) for i in cond_list]):
 do something

This also makes it easy to add another condition easily without changing the if statement by simply appending another condition to the list:

cond_list.append('cond5=="val5"')

回答 27

我通常使用:

if ((cond1 == 'val1' and cond2 == 'val2' and
     cond3 == 'val3' and cond4 == 'val4')):
    do_something()

I usually use:

if ((cond1 == 'val1' and cond2 == 'val2' and
     cond3 == 'val3' and cond4 == 'val4')):
    do_something()

回答 28

如果我们的if&else条件必须在其中执行多个语句,则我们可以像下面这样编写。每当我们有if else例子时,里面都有一个语句。

谢谢它为我工作。

#!/usr/bin/python
import sys
numberOfArgument =len(sys.argv)
weblogic_username =''
weblogic_password = ''
weblogic_admin_server_host =''
weblogic_admin_server_port =''


if numberOfArgument == 5:
        weblogic_username = sys.argv[1]
        weblogic_password = sys.argv[2]
        weblogic_admin_server_host =sys.argv[3]
        weblogic_admin_server_port=sys.argv[4]
elif numberOfArgument <5:
        print " weblogic UserName, weblogic Password and weblogic host details are Mandatory like, defalutUser, passwordForDefaultUser, t3s://server.domainname:7001 ."
        weblogic_username = raw_input("Enter Weblogic user Name")
        weblogic_password = raw_input('Enter Weblogic user Password')
        weblogic_admin_server_host = raw_input('Enter Weblogic admin host ')
        weblogic_admin_server_port = raw_input('Enter Weblogic admin port')
#enfelif
#endIf

if our if & an else condition has to execute multiple statement inside of it than we can write like below. Every when we have if else example with one statement inside of it .

Thanks it work for me.

#!/usr/bin/python
import sys
numberOfArgument =len(sys.argv)
weblogic_username =''
weblogic_password = ''
weblogic_admin_server_host =''
weblogic_admin_server_port =''


if numberOfArgument == 5:
        weblogic_username = sys.argv[1]
        weblogic_password = sys.argv[2]
        weblogic_admin_server_host =sys.argv[3]
        weblogic_admin_server_port=sys.argv[4]
elif numberOfArgument <5:
        print " weblogic UserName, weblogic Password and weblogic host details are Mandatory like, defalutUser, passwordForDefaultUser, t3s://server.domainname:7001 ."
        weblogic_username = raw_input("Enter Weblogic user Name")
        weblogic_password = raw_input('Enter Weblogic user Password')
        weblogic_admin_server_host = raw_input('Enter Weblogic admin host ')
        weblogic_admin_server_port = raw_input('Enter Weblogic admin port')
#enfelif
#endIf

回答 29

请原谅我,但是碰巧我对#Python的了解不如在座的任何人,但是碰巧我在3D BIM建模中编写自己的对象时发现了类似的东西,因此我将使算法适应python的

我在这里发现的问题是双面的:

  1. 对于可能会尝试解密脚本的人,我认为我似乎很陌生。
  2. 如果更改了这些值(最可能的话),或者必须添加新的条件(损坏的架构),则代码维护的成本将很高。

要绕过所有这些问题,您的脚本必须像这样

param_Val01 = Value 01   #give a meaningful name for param_Val(i) preferable an integer
param_Val02 = Value 02
param_Val03 = Value 03
param_Val04 = Value 04   # and ... etc

conditions = 0           # this is a value placeholder

########
Add script that if true will make:

conditions = conditions + param_Val01   #value of placeholder is updated
########

### repeat as needed


if conditions = param_Val01 + param_Val02 + param_Val03 + param_Val04:
    do something

这种方法的优点:

  1. 脚本可读。

  2. 脚本可以轻松维护。

  3. 条件是对表示所需条件的值之和进行的1比较操作。
  4. 无需多级条件

希望对大家有帮助

Pardon my noobness, but it happens that I’m not as knowledgeable of #Python as anyone of you here, but it happens that I have found something similar when scripting my own objects in a 3D BIM modeling, so I will adapt my algorithm to that of python.

The problem that I find here, is double sided:

  1. Values my seem foreign for someone who may try to decipher the script.
  2. Code maintenance will come at a high cost, if those values are changed (most probable), or if new conditions must be added (broken schema)

Do to bypass all these problems, your script must go like this

param_Val01 = Value 01   #give a meaningful name for param_Val(i) preferable an integer
param_Val02 = Value 02
param_Val03 = Value 03
param_Val04 = Value 04   # and ... etc

conditions = 0           # this is a value placeholder

########
Add script that if true will make:

conditions = conditions + param_Val01   #value of placeholder is updated
########

### repeat as needed


if conditions = param_Val01 + param_Val02 + param_Val03 + param_Val04:
    do something

Pros of this method:

  1. Script is readable.

  2. Script can be easy maintained.

  3. conditions is a 1 comparison operation to a sum of values that represents the desired conditions.
  4. No need for multilevel conditions

Hope it help you all


如何针对一个值测试多个变量?

问题:如何针对一个值测试多个变量?

我正在尝试制作一个将多个变量与一个整数进行比较并输出三个字母的字符串的函数。我想知道是否有一种方法可以将其转换为Python。所以说:

x = 0
y = 1
z = 3
mylist = []

if x or y or z == 0 :
    mylist.append("c")
if x or y or z == 1 :
    mylist.append("d")
if x or y or z == 2 :
    mylist.append("e")
if x or y or z == 3 : 
    mylist.append("f")

这将返回以下列表:

["c", "d", "f"]

这样的事情可能吗?

I’m trying to make a function that will compare multiple variables to an integer and output a string of three letters. I was wondering if there was a way to translate this into Python. So say:

x = 0
y = 1
z = 3
mylist = []

if x or y or z == 0 :
    mylist.append("c")
if x or y or z == 1 :
    mylist.append("d")
if x or y or z == 2 :
    mylist.append("e")
if x or y or z == 3 : 
    mylist.append("f")

which would return a list of:

["c", "d", "f"]

Is something like this possible?


回答 0

您误解了布尔表达式是如何工作的。它们不像英文句子那样工作,并且猜测您在这里对所有名称都使用相同的比较。您正在寻找:

if x == 1 or y == 1 or z == 1:

xy以其他方式自行评估(False如果为0,则为True)。

您可以使用针对元组的容纳测试来缩短该时间:

if 1 in (x, y, z):

还是更好:

if 1 in {x, y, z}:

使用aset来利用固定成本的成员资格测试(in无论左侧操作数是多少,都花费固定的时间)。

使用时or,python会将运算符的每一面视为单独的表达式。该表达式x or y == 1首先被视为的布尔测试x,然后如果为False,y == 1则测试该表达式。

这是由于运算符的优先级。的or操作者具有较低的优先级比所述==测试,所以后者被评估第一

但是,即使不是这种情况,并且x or y or z == 1实际上该表达式被解释为(x or y or z) == 1,该表达式仍不会执行您期望的操作。

x or y or z会求值为第一个“真实的”参数,例如,不是False,数字0或为空(有关布尔值在Python上下文中认为Python为假的详细信息,请参见布尔值表达式)。

因此,对于values x = 2; y = 1; z = 0x or y or z将解析为2,因为那是参数中的第一个真值。然后2 == 1False,即使y == 1True

反之亦然;针对单个变量测试多个值;x == 1 or 2 or 3会因为相同的原因而失败。使用x == 1 or x == 2 or x == 3x in {1, 2, 3}

You misunderstand how boolean expressions work; they don’t work like an English sentence and guess that you are talking about the same comparison for all names here. You are looking for:

if x == 1 or y == 1 or z == 1:

x and y are otherwise evaluated on their own (False if 0, True otherwise).

You can shorten that using a containment test against a tuple:

if 1 in (x, y, z):

or better still:

if 1 in {x, y, z}:

using a set to take advantage of the constant-cost membership test (in takes a fixed amount of time whatever the left-hand operand is).

When you use or, python sees each side of the operator as separate expressions. The expression x or y == 1 is treated as first a boolean test for x, then if that is False, the expression y == 1 is tested.

This is due to operator precedence. The or operator has a lower precedence than the == test, so the latter is evaluated first.

However, even if this were not the case, and the expression x or y or z == 1 was actually interpreted as (x or y or z) == 1 instead, this would still not do what you expect it to do.

x or y or z would evaluate to the first argument that is ‘truthy’, e.g. not False, numeric 0 or empty (see boolean expressions for details on what Python considers false in a boolean context).

So for the values x = 2; y = 1; z = 0, x or y or z would resolve to 2, because that is the first true-like value in the arguments. Then 2 == 1 would be False, even though y == 1 would be True.

The same would apply to the inverse; testing multiple values against a single variable; x == 1 or 2 or 3 would fail for the same reasons. Use x == 1 or x == 2 or x == 3 or x in {1, 2, 3}.


回答 1

使用以下字典结构可以更轻松地解决您的问题:

x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]

Your problem is more easily addressed with a dictionary structure like:

x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]

回答 2

正如Martijn Pieters所说,正确且最快的格式是:

if 1 in {x, y, z}:

根据他的建议,您现在将具有单独的if语句,以便Python可以读取每个语句,无论前者是True还是False。如:

if 0 in {x, y, z}:
    mylist.append("c")
if 1 in {x, y, z}:
    mylist.append("d")
if 2 in {x, y, z}:
    mylist.append("e")
...

这将起作用,但是如果您习惯使用字典(请参阅我在那做的事情),则可以通过制作一个初始字典来将数字映射到所需的字母,然后使用for循环来进行清理:

num_to_letters = {0: "c", 1: "d", 2: "e", 3: "f"}
for number in num_to_letters:
    if number in {x, y, z}:
        mylist.append(num_to_letters[number])

As stated by Martijn Pieters, the correct, and fastest, format is:

if 1 in {x, y, z}:

Using his advice you would now have separate if-statements so that Python will read each statement whether the former were True or False. Such as:

if 0 in {x, y, z}:
    mylist.append("c")
if 1 in {x, y, z}:
    mylist.append("d")
if 2 in {x, y, z}:
    mylist.append("e")
...

This will work, but if you are comfortable using dictionaries (see what I did there), you can clean this up by making an initial dictionary mapping the numbers to the letters you want, then just using a for-loop:

num_to_letters = {0: "c", 1: "d", 2: "e", 3: "f"}
for number in num_to_letters:
    if number in {x, y, z}:
        mylist.append(num_to_letters[number])

回答 3

直接的写法x or y or z == 0

if any(map((lambda value: value == 0), (x,y,z))):
    pass # write your logic.

但我不认为,您喜欢它。:)这种方式很难看。

另一种方法(更好)是:

0 in (x, y, z)

BTW很多ifs可以写成这样的东西

my_cases = {
    0: Mylist.append("c"),
    1: Mylist.append("d")
    # ..
}

for key in my_cases:
    if key in (x,y,z):
        my_cases[key]()
        break

The direct way to write x or y or z == 0 is

if any(map((lambda value: value == 0), (x,y,z))):
    pass # write your logic.

But I dont think, you like it. :) And this way is ugly.

The other way (a better) is:

0 in (x, y, z)

BTW lots of ifs could be written as something like this

my_cases = {
    0: Mylist.append("c"),
    1: Mylist.append("d")
    # ..
}

for key in my_cases:
    if key in (x,y,z):
        my_cases[key]()
        break

回答 4

如果您非常懒惰,可以将值放在数组中。如

list = []
list.append(x)
list.append(y)
list.append(z)
nums = [add numbers here]
letters = [add corresponding letters here]
for index in range(len(nums)):
    for obj in list:
        if obj == num[index]:
            MyList.append(letters[index])
            break

您也可以将数字和字母放入字典中并执行此操作,但这可能比if语句简单得多。那就是你变得更加懒惰的原因:)

还有一件事,你的

if x or y or z == 0:

会编译,但不会以您希望的方式编译。当您简单地将变量放在if语句中时(示例)

if b

程序将检查变量是否不为null。编写以上语句的另一种方法(更有意义)是

if bool(b)

Bool是python中的一个内置函数,它基本上执行验证布尔语句的命令(如果您不知道这是什么,那么它就是您现在要在if语句中创建的内容:)

我发现的另一种懒惰方式是:

if any([x==0, y==0, z==0])

If you ARE very very lazy, you can put the values inside an array. Such as

list = []
list.append(x)
list.append(y)
list.append(z)
nums = [add numbers here]
letters = [add corresponding letters here]
for index in range(len(nums)):
    for obj in list:
        if obj == num[index]:
            MyList.append(letters[index])
            break

You can also put the numbers and letters in a dictionary and do it, but this is probably a LOT more complicated than simply if statements. That’s what you get for trying to be extra lazy :)

One more thing, your

if x or y or z == 0:

will compile, but not in the way you want it to. When you simply put a variable in an if statement (example)

if b

the program will check if the variable is not null. Another way to write the above statement (which makes more sense) is

if bool(b)

Bool is an inbuilt function in python which basically does the command of verifying a boolean statement (If you don’t know what that is, it is what you are trying to make in your if statement right now :))

Another lazy way I found is :

if any([x==0, y==0, z==0])

回答 5

要检查一组变量中是否包含值,可以使用内置模块 itertoolsoperator

例如:

进口:

from itertools import repeat
from operator import contains

声明变量:

x = 0
y = 1
z = 3

创建值的映射(以您要检查的顺序):

check_values = (0, 1, 3)

使用itertools允许的变量重复:

check_vars = repeat((x, y, z))

最后,使用该map函数创建一个迭代器:

checker = map(contains, check_vars, check_values)

然后,在检查值时(按原始顺序),请使用next()

if next(checker)  # Checks for 0
    # Do something
    pass
elif next(checker)  # Checks for 1
    # Do something
    pass

等等…

这是一个优势,lambda x: x in (variables)因为operator它是内置模块,并且比必须使用lambda它来创建自定义就地功能的模块更快,更高效。

检查列表中是否存在非零(或False)值的另一个选项:

not (x and y and z)

当量:

not all((x, y, z))

To check if a value is contained within a set of variables you can use the inbuilt modules itertools and operator.

For example:

Imports:

from itertools import repeat
from operator import contains

Declare variables:

x = 0
y = 1
z = 3

Create mapping of values (in the order you want to check):

check_values = (0, 1, 3)

Use itertools to allow repetition of the variables:

check_vars = repeat((x, y, z))

Finally, use the map function to create an iterator:

checker = map(contains, check_vars, check_values)

Then, when checking for the values (in the original order), use next():

if next(checker)  # Checks for 0
    # Do something
    pass
elif next(checker)  # Checks for 1
    # Do something
    pass

etc…

This has an advantage over the lambda x: x in (variables) because operator is an inbuilt module and is faster and more efficient than using lambda which has to create a custom in-place function.

Another option for checking if there is a non-zero (or False) value in a list:

not (x and y and z)

Equivalent:

not all((x, y, z))

回答 6

设置是这里的好方法,因为它对变量进行排序,这似乎是您的目标。{z,y,x}{0,1,3}参数的任何命令。

>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']

这样,整个解决方案就是O(n)。

Set is the good approach here, because it orders the variables, what seems to be your goal here. {z,y,x} is {0,1,3} whatever the order of the parameters.

>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']

This way, the whole solution is O(n).


回答 7

这里提供的所有出色答案都集中在原始海报的特定要求上,并集中在if 1 in {x,y,z}Martijn Pieters提出的解决方案上。
他们忽略了这个问题的更广泛含义:
如何针对多个值测试一个变量?
如果使用例如字符串,则提供的解决方案不适用于部分匹配:
测试字符串“ Wild”是否为多个值

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in {x, y, z}: print (True)
... 

要么

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in [x, y, z]: print (True)
... 

在这种情况下,最容易转换为字符串

>>> [x, y, z]
['Wild things', 'throttle it back', 'in the beginning']
>>> {x, y, z}
{'in the beginning', 'throttle it back', 'Wild things'}
>>> 

>>> if "Wild" in str([x, y, z]): print (True)
... 
True
>>> if "Wild" in str({x, y, z}): print (True)
... 
True

但是,应注意,如所述@codeforester,使用此方法会丢失单词边界,例如:

>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
... 
True

这3个字母rot确实存在于列表中,但不是单个单词。测试“腐烂”将失败,但是如果列表项之一“在地狱腐烂”,那也将失败。
结果是,如果使用此方法,请注意您的搜索条件,并注意它确实有此限制。

All of the excellent answers provided here concentrate on the specific requirement of the original poster and concentrate on the if 1 in {x,y,z} solution put forward by Martijn Pieters.
What they ignore is the broader implication of the question:
How do I test one variable against multiple values?
The solution provided will not work for partial hits if using strings for example:
Test if the string “Wild” is in multiple values

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in {x, y, z}: print (True)
... 

or

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in [x, y, z]: print (True)
... 

for this scenario it’s easiest to convert to a string

>>> [x, y, z]
['Wild things', 'throttle it back', 'in the beginning']
>>> {x, y, z}
{'in the beginning', 'throttle it back', 'Wild things'}
>>> 

>>> if "Wild" in str([x, y, z]): print (True)
... 
True
>>> if "Wild" in str({x, y, z}): print (True)
... 
True

It should be noted however, as mentioned by @codeforester, that word boundries are lost with this method, as in:

>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
... 
True

the 3 letters rot do exist in combination in the list but not as an individual word. Testing for ” rot ” would fail but if one of the list items were “rot in hell”, that would fail as well.
The upshot being, be careful with your search criteria if using this method and be aware that it does have this limitation.


回答 8

我认为这样会更好地处理它:

my_dict = {0: "c", 1: "d", 2: "e", 3: "f"}

def validate(x, y, z):
    for ele in [x, y, z]:
        if ele in my_dict.keys():
            return my_dict[ele]

输出:

print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e

I think this will handle it better:

my_dict = {0: "c", 1: "d", 2: "e", 3: "f"}

def validate(x, y, z):
    for ele in [x, y, z]:
        if ele in my_dict.keys():
            return my_dict[ele]

Output:

print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e

回答 9

如果要使用if,则以下else语句是另一种解决方案:

myList = []
aList = [0, 1, 3]

for l in aList:
    if l==0: myList.append('c')
    elif l==1: myList.append('d')
    elif l==2: myList.append('e')
    elif l==3: myList.append('f')

print(myList)

If you want to use if, else statements following is another solution:

myList = []
aList = [0, 1, 3]

for l in aList:
    if l==0: myList.append('c')
    elif l==1: myList.append('d')
    elif l==2: myList.append('e')
    elif l==3: myList.append('f')

print(myList)

回答 10

d = {0:'c', 1:'d', 2:'e', 3: 'f'}
x, y, z = (0, 1, 3)
print [v for (k,v) in d.items() if x==k or y==k or z==k]
d = {0:'c', 1:'d', 2:'e', 3: 'f'}
x, y, z = (0, 1, 3)
print [v for (k,v) in d.items() if x==k or y==k or z==k]

回答 11

此代码可能会有所帮助

L ={x, y, z}
T= ((0,"c"),(1,"d"),(2,"e"),(3,"f"),)
List2=[]
for t in T :
if t[0] in L :
    List2.append(t[1])
    break;

This code may be helpful

L ={x, y, z}
T= ((0,"c"),(1,"d"),(2,"e"),(3,"f"),)
List2=[]
for t in T :
if t[0] in L :
    List2.append(t[1])
    break;

回答 12

您可以尝试以下显示的方法。在这种方法中,您可以自由指定/输入要输入的变量数。

mydict = {0:"c", 1:"d", 2:"e", 3:"f"}
mylist= []

num_var = int(raw_input("How many variables? ")) #Enter 3 when asked for input.

for i in range(num_var): 
    ''' Enter 0 as first input, 1 as second input and 3 as third input.'''
    globals()['var'+str('i').zfill(3)] = int(raw_input("Enter an integer between 0 and 3 "))
    mylist += mydict[globals()['var'+str('i').zfill(3)]]

print mylist
>>> ['c', 'd', 'f']

You can try the method shown below. In this method, you will have the freedom to specify/input the number of variables that you wish to enter.

mydict = {0:"c", 1:"d", 2:"e", 3:"f"}
mylist= []

num_var = int(raw_input("How many variables? ")) #Enter 3 when asked for input.

for i in range(num_var): 
    ''' Enter 0 as first input, 1 as second input and 3 as third input.'''
    globals()['var'+str('i').zfill(3)] = int(raw_input("Enter an integer between 0 and 3 "))
    mylist += mydict[globals()['var'+str('i').zfill(3)]]

print mylist
>>> ['c', 'd', 'f']

回答 13

一线解决方案:

mylist = [{0: 'c', 1: 'd', 2: 'e', 3: 'f'}[i] for i in [0, 1, 2, 3] if i in (x, y, z)]

要么:

mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]

One line solution:

mylist = [{0: 'c', 1: 'd', 2: 'e', 3: 'f'}[i] for i in [0, 1, 2, 3] if i in (x, y, z)]

Or:

mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]

回答 14

也许您需要直接的公式来设置输出位。

x=0 or y=0 or z=0   is equivalent to x*y*z = 0

x=1 or y=1 or z=1   is equivalent to (x-1)*(y-1)*(z-1)=0

x=2 or y=2 or z=2   is equivalent to (x-2)*(y-2)*(z-2)=0

让我们映射到位: 'c':1 'd':0xb10 'e':0xb100 'f':0xb1000

isc(是’c’)的关系:

if xyz=0 then isc=1 else isc=0

如果公式https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315使用数学

[C]: (xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))

[d]: ((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))

通过以下逻辑连接这些公式:

  • 逻辑and是方程的平方和
  • 逻辑or是方程式的产物

你会有一个总和表示总和,你总和公式

那么sum&1是c,sum&2是d,sum&4是e,sum&5是f

之后,您可以形成预定义的数组,其中字符串元素的索引将对应于就绪字符串。

array[sum] 给你字符串。

Maybe you need direct formula for output bits set.

x=0 or y=0 or z=0   is equivalent to x*y*z = 0

x=1 or y=1 or z=1   is equivalent to (x-1)*(y-1)*(z-1)=0

x=2 or y=2 or z=2   is equivalent to (x-2)*(y-2)*(z-2)=0

Let’s map to bits: 'c':1 'd':0xb10 'e':0xb100 'f':0xb1000

Relation of isc (is ‘c’):

if xyz=0 then isc=1 else isc=0

Use math if formula https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315

[c]: (xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))

[d]: ((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))

Connect these formulas by following logic:

  • logic and is the sum of squares of equations
  • logic or is the product of equations

and you’ll have a total equation express sum and you have total formula of sum

then sum&1 is c, sum&2 is d, sum&4 is e, sum&5 is f

After this you may form predefined array where index of string elements would correspond to ready string.

array[sum] gives you the string.


回答 15

它可以很容易地完成

for value in [var1,var2,var3]:
     li.append("targetValue")

It can be done easily as

for value in [var1,var2,var3]:
     li.append("targetValue")

回答 16

用Python表示伪代码的最简便的方法是:

x = 0
y = 1
z = 3
mylist = []

if any(v == 0 for v in (x, y, z)):
    mylist.append("c")
if any(v == 1 for v in (x, y, z)):
    mylist.append("d")
if any(v == 2 for v in (x, y, z)):
    mylist.append("e")
if any(v == 3 for v in (x, y, z)):
    mylist.append("f")

The most mnemonic way of representing your pseudo-code in Python would be:

x = 0
y = 1
z = 3
mylist = []

if any(v == 0 for v in (x, y, z)):
    mylist.append("c")
if any(v == 1 for v in (x, y, z)):
    mylist.append("d")
if any(v == 2 for v in (x, y, z)):
    mylist.append("e")
if any(v == 3 for v in (x, y, z)):
    mylist.append("f")

回答 17

要使用一个值测试多个变量: if 1 in {a,b,c}:

要使用一个变量测试多个值: if a in {1, 2, 3}:

To test multiple variables with one single value: if 1 in {a,b,c}:

To test multiple values with one variable: if a in {1, 2, 3}:


回答 18

看起来您正在构建某种凯撒密码。

更为通用的方法是:

input_values = (0, 1, 3)
origo = ord('c')
[chr(val + origo) for val in inputs]

输出

['c', 'd', 'f']

不确定这是否是代码的理想副作用,但是输出的顺序将始终排序。

如果这是您想要的,可以将最后一行更改为:

sorted([chr(val + origo) for val in inputs])

Looks like you’re building some kind of Caesar cipher.

A much more generalized approach is this:

input_values = (0, 1, 3)
origo = ord('c')
[chr(val + origo) for val in inputs]

outputs

['c', 'd', 'f']

Not sure if it’s a desired side effect of your code, but the order of your output will always be sorted.

If this is what you want, the final line can be changed to:

sorted([chr(val + origo) for val in inputs])

回答 19

您可以使用字典:

x = 0
y = 1
z = 3
list=[]
dict = {0: 'c', 1: 'd', 2: 'e', 3: 'f'}
if x in dict:
    list.append(dict[x])
else:
    pass

if y in dict:
    list.append(dict[y])
else:
    pass
if z in dict:
    list.append(dict[z])
else:
    pass

print list

You can use dictionary :

x = 0
y = 1
z = 3
list=[]
dict = {0: 'c', 1: 'd', 2: 'e', 3: 'f'}
if x in dict:
    list.append(dict[x])
else:
    pass

if y in dict:
    list.append(dict[y])
else:
    pass
if z in dict:
    list.append(dict[z])
else:
    pass

print list

回答 20

如果没有字典,请尝试以下解决方案:

x, y, z = 0, 1, 3    
offset = ord('c')
[chr(i + offset) for i in (x,y,z)]

并给出:

['c', 'd', 'f']

Without dict, try this solution:

x, y, z = 0, 1, 3    
offset = ord('c')
[chr(i + offset) for i in (x,y,z)]

and gives:

['c', 'd', 'f']

回答 21

这将为您提供帮助。

def test_fun(val):
    x = 0
    y = 1
    z = 2
    myList = []
    if val in (x, y, z) and val == 0:
        myList.append("C")
    if val in (x, y, z) and val == 1:
        myList.append("D")
    if val in (x, y, z) and val == 2:
        myList.append("E")

test_fun(2);

This will help you.

def test_fun(val):
    x = 0
    y = 1
    z = 2
    myList = []
    if val in (x, y, z) and val == 0:
        myList.append("C")
    if val in (x, y, z) and val == 1:
        myList.append("D")
    if val in (x, y, z) and val == 2:
        myList.append("E")

test_fun(2);

回答 22

你可以团结起来

x = 0
y = 1
z = 3

在一个变量中。

In [1]: xyz = (0,1,3,) 
In [2]: mylist = []

将我们的条件更改为:

In [3]: if 0 in xyz: 
    ...:     mylist.append("c") 
    ...: if 1 in xyz: 
    ...:     mylist.append("d") 
    ...: if 2 in xyz: 
    ...:     mylist.append("e") 
    ...: if 3 in xyz:  
    ...:     mylist.append("f") 

输出:

In [21]: mylist                                                                                
Out[21]: ['c', 'd', 'f']

You can unite this

x = 0
y = 1
z = 3

in one variable.

In [1]: xyz = (0,1,3,) 
In [2]: mylist = []

Change our conditions as:

In [3]: if 0 in xyz: 
    ...:     mylist.append("c") 
    ...: if 1 in xyz: 
    ...:     mylist.append("d") 
    ...: if 2 in xyz: 
    ...:     mylist.append("e") 
    ...: if 3 in xyz:  
    ...:     mylist.append("f") 

Output:

In [21]: mylist                                                                                
Out[21]: ['c', 'd', 'f']

回答 23

问题

同时测试多个值的模式

>>> 2 in {1, 2, 3}
True
>>> 5 in {1, 2, 3}
False

具有很高的可读性,并且可以在许多情况下工作,但有一个陷阱:

>>> 0 in {True, False}
True

但是我们想要

>>> (0 is True) or (0 is False)
False

先前表达式的一种概括是基于ytpillai的答案:

>>> any([0 is True, 0 is False])
False

可以写成

>>> any(0 is item for item in (True, False))
False

虽然此表达式返回正确的结果,但它不如第一个表达式可读:

Problem

While the pattern for testing multiple values

>>> 2 in {1, 2, 3}
True
>>> 5 in {1, 2, 3}
False

is very readable and is working in many situation, there is one pitfall:

>>> 0 in {True, False}
True

But we want to have

>>> (0 is True) or (0 is False)
False

Solution

One generalization of the previous expression is based on the answer from ytpillai:

>>> any([0 is True, 0 is False])
False

which can be written as

>>> any(0 is item for item in (True, False))
False

While this expression returns the right result it is not as readable as the first expression :-(