我想遍历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
所有有问题的文件都具有非常相似的名称结构。感谢您的帮助。
答案 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。