¿Por qué estas cadenas se escapan de mi expresión regular en Python?

In my code, I load up an entire folder into a list and then try to get rid of every file in the list except the .mp3 files.

import os
import re
path = '/home/user/mp3/'
dirList = os.listdir(path)
dirList.sort()
i = 0
for names in dirList:
  match = re.search(r'\.mp3', names)
  if match:
    i = i+1
  else:
    dirList.remove(names)
print dirList
print i

After I run the file, the code does get rid of some files in the list but keeps these two especifically:

['00. Various Artists - Indie Rock Playlist October 2008.m3u', '00. Various Artists - Indie Rock Playlist October 2008.pls']

I can't understand what's going on, why are those two specifically escaping my search.

preguntado el 08 de enero de 11 a las 21:01

3 Respuestas

You are modifying your list inside a loop. That can cause issues. You should loop over a copy of the list instead (for name in dirList[:]:), or create a new list.

modifiedDirList = []
for name in dirList:
    match = re.search(r'\.mp3', name)
    if match:
        i += 1
        modifiedDirList.append(name)

print modifiedDirList

Or even better, use a list comprehension:

dirList = [name for name in sorted(os.listdir(path))
           if re.search(r'\.mp3', name)]

The same thing, without a regular expression:

dirList = [name for name in sorted(os.listdir(path))
           if name.endswith('.mp3')]

Respondido el 10 de enero de 11 a las 05:01

Thank you very much :) I'm new to python and there's a bunch of things to learn! - marcoamorales

your list comprehensions are nonsense. - SilentGhost

@SilentGhost - Nonsense? How so? - Seth

TypeError: 'NoneType' object is not iterable - marcoamorales

Ok, found the error, you can't sort on os.listdir(path). You have to do it on your own list. - marcoamorales

maybe you should use the glob module - here is you entire script:

>>> import glob
>>> mp3s = sorted(glob.glob('*.mp3'))
>>> print mp3s
>>> print len(mp3s)

Respondido el 09 de enero de 11 a las 00:01

glob.iglob would be perfect. - SilentGhost

As soon as you call dirList.remove(names), the original iterator doesn't do what you want. If you iterate over a copy of the list, it will work as expected:

for names in dirList[:]:
    ....

Alternativamente, puede utilizar lista de comprensiones to construct the right list:

dirList = [name for name in dirList if re.search(r'\.mp3', name)]

Respondido el 09 de enero de 11 a las 00:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.