从列表中删除非图像文件

时间:2020-03-25 22:44:21

标签: python

假设我要删除所有不代表jpg或png文件的列表项。

arr = ['doc01.pdf', 'doc02.pdf', 'img01.PNG', 'img02.jpg']
for i in arr:
    if i.lower().find("jpg") == -1 and i.lower().find("jpeg") == -1 and i.lower().find("png") == -1:
        arr.remove(i)
print(arr) 

我为什么得到这个:

['doc02.pdf', 'img02.jpg']

我认为pdf的所有3个比较都应该变为真实,因此应将其删除。

3 个答案:

答案 0 :(得分:1)

就像@ scott-hunter一样,您不想修改要遍历的列表。

在这种情况下,理想情况下,您将制作一份副本,将其放入循环中,使用基于索引的for循环,或者更好地利用它来发挥作用。使用filter

filter(lambda f: f.lower().endswith(('.jpg', '.jpeg', '.png')), arr)
// input: arr = ['doc01.pdf', 'doc02.pdf', 'img01.PNG', 'img02.jpg']
// output: ['img01.PNG', 'img02.jpg']

编辑:

整洁,@ HSK建议itertools.filterfalse删除。

list(itertools.filterfalse(lambda f: f.lower().endswith(('.jpg', '.jpeg', '.png')), arr))
// input: arr = ['doc01.pdf', 'doc02.pdf', 'img01.PNG', 'img02.jpg']
// output: ['doc01.pdf', 'doc02.pdf']

答案 1 :(得分:1)

这个问题是一个非常基本的问题,因此一些解释可能会有用。

解决方法之一:

arr = ['do.jpg.c01.pdf', 'pngdoc02.pdf', 'img01.PNG', 'img02.jpg']
ar=[]
for i in arr:
    j=i.lower()
    if j[-4:] == '.jpg' \
       or j[-4:] == '.png' \
       or j[-5:] == '.jpeg':
        ar.append(i)

print(ar)

说明:

  1. j = i.lower()对于每次循环运行仅计算一次,
  2. 用\字符分隔行进一步提高了可读性
  3. “或”使条件仅计算到第一次匹配,
    同时“和”会强制计算每个循环中的所有三个条件。
    因此,条件的顺序很重要
  4. find()带有不带点的参数(例如:'jpg')会击中 arr列表,在添加点(例如:.jpg)后找到第一个元素会出错。

    字符串切片解决了这个问题

答案 2 :(得分:1)

no_img = [ _ for _ in arr if not (_.lower().endswith("img") or _.lower().endswith("jpg")) ]