Reputation: 39
Suppose I want to remove all list items that do not stand for jpg or png files.
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)
Why am I getting this:
['doc02.pdf', 'img02.jpg']
I thought all 3 comparisons should become true for the pdfs and this they should be removed.
Upvotes: 0
Views: 532
Reputation: 1287
Like @scott-hunter said you don't want to modify the list you are looping over.
In that case, you ideally would make a copy that you would feed into the loop, use index-based for loop or better you get functional with it. Use a 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']
Edit:
Neat, @HSK's suggestion of itertools.filterfalse
to remove.
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']
Upvotes: 1
Reputation:
no_img = [ _ for _ in arr if not (_.lower().endswith("img") or _.lower().endswith("jpg")) ]
Upvotes: 1
Reputation: 1325
The question is at a very basic level so some explanations can be useful.
One of the ways to solve:
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)
Explanation:
find() with arguments without a dot (ex: 'jpg') would have hit all elements of the arr list,find after adding a dot (ex: '.jpg') would have gone wrong first element.
String slices solve this problem
Upvotes: 1