为什么我的if语句会产生假阴性?

时间:2018-06-27 16:37:16

标签: python if-statement jupyter-notebook

我想遍历Python 3中的文件列表。它们是包含矩阵的CSV文件。我想对所有这些文件都执行同样的操作,因此我想创建一个包含其名称的列表,从列表中删除文件夹中的所有其他文件,并使用相关内容进行转换。

我的目标文件都以“ 2m.csv”结尾(例如:14-17_CCK_all_2m.csv),而我在过程结束时的结果将以“ 1m.csv”结尾。仍然,当我在Jupyter笔记本中运行以下脚本时,结果仍然包含一些以“ 1m.csv”结尾的文件(它们在开发的早期阶段就一直存在)

import os
myfiles = os.listdir()

for item in myfiles:
    if item[-6:] != "2m.csv":
        myfiles.remove(item)

有趣的是,如果我在单独的行中测试一个假否定词,我会得到一个True答案,因此if语句应该从上面脚本的列表中删除它-它是对其中一些字符所做的,但不是与其他人:

myfiles[1][-6:] != "2m.csv"
>>> True

所有有问题的文件都具有非常相似的名称结构。感谢您的帮助。

4 个答案:

答案 0 :(得分:0)

更好地使用列表理解:

myfiles = [x for x in os.listdir() if x[-6:] == '2m.csv']

我更喜欢使用endswith()方法,而不是切片:

myfiles = [x for x in os.listdir() if x.endswith('2m.csv')]

答案 1 :(得分:0)

问题似乎出现在您的for循环中。您正在遍历并修改myfiles

解决方案是内联过滤掉错误的文件名。

import os
myfiles = [ item for item in os.listdir() if item[-6:] == "2m.cvs" ]

答案 2 :(得分:0)

要在filter中使用Python列表,请不要使用for循环对其进行迭代。最好使用list comprehensions

所以它看起来像这样:

import os
myfiles = [f for f in os.listdir() if f[-6:] == "2m.csv"]

它更干净,通常在基准上更快,并且可以完成您想要的工作(而且比map/filter干净得多-但这是我的主观意见)

答案 3 :(得分:0)

修改集合/列表-迭代它总是很可能会产生这种差异。如果在print语句之前添加if语句,可能会看到"2m.csv"无法打印。这是因为当您从列表中删除列表时,该列表将重新索引,并且迭代有效地跳过了该项目。

链接重复项中给出的解决方案是使用列表理解:

myfiles = [item for item in myfiles if item[-6:] == "2m.csv"]

或者,如果您更喜欢使用for循环,则需要向后迭代,以便删除项目(以及随后的重新索引编制)不会影响其余项目。

for i in range(len(myfiles)-1,-1,-1):
    if myfiles[i][-6:] != "2m.csv":
        myfiles.remove(i)

但是列表推导方法会更简洁,更pythonic。

相关问题