Dans ma première version, il semble que j'ai mal interprété votre question. Donc, si j'ai bien compris, vous essayez de traiter une liste de fichiers afin que vous puissiez facilement accéder à tous les noms de fichiers avec une extension donnée, ou tous les noms de fichiers avec une base donnée ("base" étant la partie avant le période)?
Si tel est le cas, je recommanderais de cette façon:
from itertools import groupby
def group_by_name(filenames):
'''Puts the filenames in the given iterable into a dictionary where
the key is the first component of the filename and the value is
a list of the filenames with that component.'''
keyfunc = lambda f: f.split('.', 1)[0]
return dict((k, list(g)) for k,g in groupby(
sorted(filenames, key=keyfunc), key=keyfunc
))
Par exemple, étant donné la liste
>>> test_data = [
... exia.frame, exia.head, exia.swords, exia.legs,
... exia.arms, exia.pilot, exia.gn_drive, lockon_stratos.data,
... tieria_erde.data, ribbons_almark.data, otherstuff.dada
... ]
cette fonction produirait
>>> group_by_name(test_data)
{'exia': ['exia.arms', 'exia.frame', 'exia.gn_drive', 'exia.head',
'exia.legs', 'exia.pilot', 'exia.swords'],
'lockon_stratos': ['lockon_stratos.data'],
'otherstuff': ['otherstuff.dada'],
'ribbons_almark': ['ribbons_almark.data'],
'tieria_erde': ['tieria_erde.data']}
Si vous vouliez indexer les noms de fichiers par extension à la place, une légère modification le fera pour vous:
def group_by_extension(filenames):
'''Puts the filenames in the given iterable into a dictionary where
the key is the last component of the filename and the value is
a list of the filenames with that extension.'''
keyfunc = lambda f: f.split('.', 1)[1]
return dict((k, list(g)) for k,g in groupby(
sorted(filenames, key=keyfunc), key=keyfunc
))
La seule différence est dans la ligne keyfunc = ...
, où je l'ai changé la clé de 0 à 1. Exemple:
>>> group_by_extension(test_data)
{'arms': ['exia.arms'],
'dada': ['otherstuff.dada'],
'data': ['lockon_stratos.data', 'ribbons_almark.data', 'tieria_erde.data'],
'frame': ['exia.frame'],
'gn_drive': ['exia.gn_drive'],
'head': ['exia.head'],
'legs': ['exia.legs'],
'pilot': ['exia.pilot'],
'swords': ['exia.swords']}
Si vous souhaitez obtenir ces deux groupes en même temps, cependant, Je pense qu'il vaudrait mieux éviter une compréhension de liste, car cela ne peut que les traiter d'une manière ou d'une autre, il ne peut pas construire deux dictionnaires différents à la fois.
from collections import defaultdict
def group_by_both(filenames):
'''Puts the filenames in the given iterable into two dictionaries,
where in the first, the key is the first component of the filename,
and in the second, the key is the last component of the filename.
The values in each dictionary are lists of the filenames with that
base or extension.'''
by_name = defaultdict(list)
by_ext = defaultdict(list)
for f in filenames:
name, ext = f.split('.', 1)
by_name[name] += [f]
by_ext[ext] += [f]
return by_name, by_ext
Je suis très bien avec itérer dans la liste, mais je me demandais s'il y avait une solution plus générique (et simple). Donc, si je devais changer le format de .gundam en .flag, je pourrais utiliser le même code. Je pourrais itérer la liste et les ajouter manuellement à une carte pour voir ce qui correspond à la première ou deuxième partie du nom de fichier, mais cela entraînerait beaucoup plus de code. –
OK, je pense que peut-être mon dernier exemple de code dans la version éditée est plus ce que vous cherchez. Si toutes vos conditions spécifient le début ou la fin du nom de fichier, vous pouvez utiliser les méthodes de chaîne 'startswith' et' endswith' au lieu des expressions régulières, ce qui peut économiser un peu de temps de calcul, mais le code sera plus long (mais Je pourrais éditer de cette façon aussi, si vous voulez). –
@Setsuna: Eh bien, je pense que vous pouvez utiliser os.listdir (chemin) itérer sur le répertoire et obtenir toutes les extensions disponibles, puis, avec cette liste, vous pouvez les regrouper comme David a dit. –