我在名为files的列表中拥有目录的所有文件名。我想过滤它,所以只剩下.php扩展名的文件。
for x in files:
if x.find(".php") == -1:
files.remove(x)
但这似乎跳过了文件名。我该怎么办?
答案 0 :(得分:10)
简单列表理解怎么样?
files = [f for f in files if f.endswith('.php')]
或者如果您更喜欢生成器:
files = (f for f in files if f.endswith('.php'))
答案 1 :(得分:5)
>>> files = ['a.php', 'b.txt', 'c.html', 'd.php']
>>> [f for f in files if f.endswith('.php')]
['a.php', 'd.php']
答案 2 :(得分:1)
提供的大多数答案都给出了列表/生成器的理解,这可能是你想要90%的时间去的方式,特别是如果你不想修改原始列表。
但是,对于那些(比如尺寸原因)你想要修改原始列表的情况,我通常会使用以下代码段:
idx = 0
while idx < len(files):
if files[idx].find(".php") == -1:
del files[idx]
else:
idx += 1
至于为什么你的原始代码没有工作 - 它正在改变列表,因为你迭代它...“for x in files”隐式创建一个迭代器,就像你做了“for x in in iter(files)“,并且删除列表中的元素会使迭代器混淆它所处的位置。对于这种情况,我通常使用上面的代码,或者如果它在项目中发生很多,将其分解为函数,例如:
def filter_in_place(func, target):
idx = 0
while idx < len(target):
if func(target[idx)):
idx += 1
else:
del target[idx]
答案 3 :(得分:0)
偶然发现了这个老问题。这里的许多解决方案都可以完成这项工作,但是他们忽略了一个文件名可能只是&#34; .php&#34;的情况。我怀疑问题是关于如何过滤PHP脚本和#34; .php&#34;可能不是一个PHP脚本。我建议的解决方案如下:
>>> import os.path
>>> files = ['a.php', 'b.txt', 'c.html', 'd.php', '.php']
>>> [f for f in files if os.path.splitext(f)[1] == ".php"]