【问题标题】:Python logical or operator acting strangePython 逻辑或运算符表现奇怪
【发布时间】:2012-05-03 07:33:17
【问题描述】:
我正在尝试在单行 for 循环中使用扩展名为 '.png'、'.jpg' 或 'jpeg' 的文件填充名为 images 的列表。我通过使用逻辑 or 运算符尝试了这一点,但这只会导致一个空列表。
images = [i for i in os.listdir('.') if i[-4:] == ('.png' or '.jpg' or 'jpeg')]
如何检查 '.png'、'.jpg' 或 'jpeg' 是否是文件的最后 4 个字符,同时将它们全部放在一行 for 循环中?
【问题讨论】:
标签:
python
for-loop
arraylist
operators
boolean
【解决方案1】:
使用in 运算符:
images = [i for i in os.listdir('.') if i[-4:] in ('.png', '.jpg', 'jpeg')]
更好的是,不要只检查最后 4 个字符,而是使用 os.path.splitext():
images = [i for i in os.listdir('.') if os.path.splitext(i)[1] in ('.png', '.jpg', '.jpeg')]
如果您想知道为什么您的代码不起作用:('.png' or '.jpg' or 'jpeg') == '.png',因为它是第一个不虚假的值。
【解决方案2】:
在您编写时,python 计算 ('.png' or '.jpg' or 'jpeg'),并将 i[-4:] 与结果进行比较。
您可能想要的是@ThiefMaster 建议的:in 运算符。
【解决方案3】:
表达式('.png' 或 '.jpg' 或 'jpeg')实际上首先被评估为 '.png',并且可能与您预期的不同。
你可以试试:
images = [i for i in os.listdir('.') if i[-4:] in ('.png', '.jpg', 'jpeg')]
【解决方案4】:
您可以为此目的使用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']
【解决方案5】:
使用or 是一个布尔表达式,它检查表达式中的任何值是否计算为True。
i[-4:] == ('.png' or '.jpg' or 'jpeg')
判断i[-4:]是否等于:
('.png' or '.jpg' or 'jpeg')
检查每个值是否为True,如果没有True 值,则返回第一个True 值或最后一个值。在这种情况下,它们都计算为 True,因为只有空字符串计算为 False,所以 '.png' 是表达式的结果。
你可以通过这样做来解决这个问题
[i for i in os.listdir('.') if i[-4:] in ('.png', '.jpg', 'jpeg')]
或者更好的方法
[i for i in os.listdir('.') if os.path.splitext(i)[1] in ('.png','.jpg','.jpeg')]
【解决方案6】:
其他答案建议在此处使用in,但您可能更喜欢的另一种方法是使用str.endswith() 方法:
extensions = '.png', '.jpg', '.jpeg'
images = [i for i in os.listdir('.') if i.endswith(extensions)]
这样做的好处是您不必在 .jpeg 上伪造匹配:您可以检查任何长度的扩展名(甚至将列表存储在与其余代码分开的地方)而不必担心破坏代码比其他代码短或长。