简体   繁体   English

Python逻辑或运算符表现奇怪

[英]Python logical or operator acting strange

I am trying to populate a list called images with files that have the extensions '.png' , '.jpg' or 'jpeg' in a one line for loop. 我正在尝试使用一行在循环中具有扩展名'.png''.jpg''jpeg'文件填充名为images的列表。 I tried this by using the logical or operator but that only resulted in an empty list. 我通过使用逻辑or运算符尝试了此操作,但这仅导致一个空列表。

images = [i for i in os.listdir('.') if i[-4:] == ('.png' or '.jpg' or 'jpeg')]

How do I check to see if '.png' , '.jpg' or 'jpeg' are the last 4 characters of the file while keeping it all in a one line for loop? 如何检查'.png''.jpg''jpeg'是否是文件的最后4个字符,同时将它们全部放在一行中进行循环?

Other answers have suggested using in here, but another way that you might prefer is to use the str.endswith() method: 建议in此处使用其他答案,但您可能更喜欢的另一种方法是使用str.endswith()方法:

extensions = '.png', '.jpg', '.jpeg'
images = [i for i in os.listdir('.') if i.endswith(extensions)]

This has the advantage that you don't have to fudge the match on .jpeg : you can check for extensions of any length (even storing the list somewhere separate from the rest of the code) without having to worry about breaking the code if any are shorter or longer than the others. 这样做的好处是您不必在.jpeg.jpeg比赛:您可以检查任何长度的扩展名(甚至将列表与其他代码分开存储),而不必担心会破坏代码(如果有)比其他短或长。

Use the in operator: 使用in运算符:

images = [i for i in os.listdir('.') if i[-4:] in ('.png', '.jpg', 'jpeg')]

Even better, instead of just checking the last 4 characters use os.path.splitext() : 更好的是,使用os.path.splitext()而不是仅检查最后四个字符:

images = [i for i in os.listdir('.') if os.path.splitext(i)[1] in ('.png', '.jpg', '.jpeg')]

In case you wonder why your code did not work: ('.png' or '.jpg' or 'jpeg') == '.png' since it's the first value that's not falsy. 如果您想知道为什么代码无法正常工作:( ('.png' or '.jpg' or 'jpeg') == '.png' .png ('.png' or '.jpg' or 'jpeg') == '.png'因为它是第一个不伪造的值。

As you wrote it, python evaluates ('.png' or '.jpg' or 'jpeg') , and compares i[-4:] to the result. 在编写时,python求值('.png' or '.jpg' or 'jpeg') ,并将i[-4:]与结果进行比较。

What you probably want is what @ThiefMaster suggests: the in operator. 您可能想要的是@ThiefMaster建议: in运算符。

You can use the fnmatch module for this purpose. 您可以为此目的使用fnmatch模块。

>>> extensions = ['*.jpg','*.png','*.jpeg']
>>> [file for file in os.listdir(".") for ext in extensions if fnmatch.fnmatch(file,ext)]
['1.png', '2.jpg', '3.jpeg']

The expression ('.png' or '.jpg' or 'jpeg') is actually evaluated to just '.png' first, and is probably not behaving as you expect. 表达式(“ .png”或“ .jpg”或“ jpeg”)实际上首先被评估为仅“ .png”,并且可能表现出与您期望的不一样的行为。

You can instead try: 您可以尝试:

images = [i for i in os.listdir('.') if i[-4:] in ('.png', '.jpg', 'jpeg')]

Using or is a boolean expression which checks if any value in the expression evaluates to True . 使用or一个布尔表达式,它检查表达式中的任何值是否为True

i[-4:] == ('.png' or '.jpg' or 'jpeg')

evaluates if i[-4:] is equal to: 评估i[-4:]是否等于:

('.png' or '.jpg' or 'jpeg') 

which checks if each value is True and returns the first True value or the last value if there are no True values. 它检查每个值是否为True ,如果没有True值,则返回第一个True值或最后一个值。 In this case they all evaluate to True as only empty strings evaluate to False so '.png' is the result of the expression. 在这种情况下,它们都评估为True因为只有空字符串评估为False因此'.png'是表达式的结果。

You can fix this by doing 您可以通过执行此操作来解决此问题

[i for i in os.listdir('.') if i[-4:] in ('.png', '.jpg', 'jpeg')]

Or a better way 还是更好的方法

[i for i in os.listdir('.') if os.path.splitext(i)[1] in ('.png','.jpg','.jpeg')]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM