J'essaie de retourner une liste donnée avec une fonction.
def get_ext(file_type):
text = ['txt', 'doc']
audio = ['mp3', 'wav']
video = ['mp4', 'mkv']
return ?????
get_ext('audio') #should return de list ['mp3', 'wav']
Alors je suis coincé. Ceci est un exemple simple/court d'une grande liste d'extensions . Quel est le moyen le plus simple de le faire?
Dans la plupart des cas, un dictionnaire ordinaire fera très bien l'affaire.
>>> get_ext = {'text': ['txt', 'doc'],
... 'audio': ['mp3', 'wav'],
... 'video': ['mp4', 'mkv']
... }
>>>
>>> get_ext['video']
['mp4', 'mkv']
Si vous voulez vraiment ou avez besoin d’une fonction (pour laquelle il peut y avoir des raisons valables), vous avez deux options. Une des plus faciles consiste à affecter à la méthode get
du dictionnaire. Vous pouvez même réaffecter le nom get_ext
si vous n'avez pas utilisé le dictionnaire derrière le rideau.
>>> get_ext = get_ext.get
>>> get_ext('video')
['mp4', 'mkv']
Cette fonction retournera None
par défaut si vous entrez une clé inconnue:
>>> x = get_ext('binary')
>>> x is None
True
Si vous souhaitez plutôt utiliser une KeyError
pour les clés inconnues, affectez-le à get_ext.__getitem__
au lieu de get_ext.get
.
Si vous voulez une valeur par défaut personnalisée, une approche consiste à envelopper le dictionnaire dans une fonction. Cet exemple utilise une liste vide comme valeur par défaut.
def get_ext(file_type):
types = {'text': ['txt', 'doc'],
'audio': ['mp3', 'wav'],
'video': ['mp4', 'mkv']
}
return types.get(file_type, [])
Cependant, @omri_saadon a fait remarquer que l’affectation types = ...
est effectuée à chaque appel de fonction. Voici ce que vous pouvez faire pour contourner cela si cela vous dérange.
class get_ext(object):
def __init__(self):
self.types = {'text': ['txt', 'doc'],
'audio': ['mp3', 'wav'],
'video': ['mp4', 'mkv']
}
def __call__(self, file_type):
return self.types.get(file_type, [])
get_ext = get_ext()
Vous pouvez utiliser get_ext
comme une fonction normale à partir de maintenant, car les callables sont finalement des callables. :)
Notez que cette approche - outre le fait que self.types
n'est créé qu'une seule fois - présente l'avantage considérable de pouvoir changer facilement les types de fichiers reconnus par votre fonction.
>>> get_ext.types['binary'] = ['bin', 'exe']
>>> get_ext('binary')
['bin', 'exe']
Si vous ne souhaitez pas définir une dictionary
comme dans @timgeb's answer
, vous pouvez appeler local()
qui vous donne une dictionary
de la variables
actuelle disponible.
def get_ext(file_type):
text = ['txt', 'doc']
audio = ['mp3', 'wav']
video = ['mp4', 'mkv']
return locals()[file_type]
et un test pour montrer que cela fonctionne:
>>> get_ext("text")
['txt', 'doc']
Vous pouvez facilement utiliser dict avec les valeurs Tuple/list comme ceci:
def get_ext(file_type):
d = {'text': ['txt', 'doc'],
'audio': ['mp3', 'wav'],
'video': ['mp4', 'mkv']}
return d[file_type]
print(get_ext('audio'))
Selon la réponse de @timgeb, j'utiliserais un dictionnaire, mais si vous en avez beaucoup accès, accordez une importance particulière à la rapidité et ne souhaitez pas définir de classe, vous pouvez utiliser la mise en cache.
from functools import lru_cache
def get_ext(file_type):
d = {'text': ['txt', 'doc'],
'audio': ['mp3', 'wav'],
'video': ['mp4', 'mkv']}
return d[file_type]
@lru_cache(maxsize=3, typed=False)
def get_ext_cached(file_type):
d = {'text': ['txt', 'doc'],
'audio': ['mp3', 'wav'],
'video': ['mp4', 'mkv']}
return d[file_type]
from timeit import timeit
# non cached
print(timeit(stmt='get_ext("text")', globals={'get_ext': get_ext}))
# 0.48447531609922706 on my machine
# cached
print(timeit(stmt='get_ext("text")', globals={'get_ext': get_ext_cached}))
# 0.11434909792297276
Bien que dans ce cas particulier, il y ait probablement trop de ressources et vous pouvez simplement appeler get sur le dictionnaire directement (le cache construit simplement son propre dictionnaire et le fait exactement), vous pouvez l'utiliser à l'avenir pour toutes les fonctions pures qui sont effectivement une recherche calculée.
d = {'text': ['txt', 'doc'],
'audio': ['mp3', 'wav'],
'video': ['mp4', 'mkv']}
# 0.05016115184298542
print(timeit(stmt="d['text']",
globals={'d':d,'c':c}))
Utilise le dictionnaire:
def get_ext(file_type):
d = {'text' : ['txt', 'doc'],
'audio' : ['mp3', 'wav'],
'video' : ['mp4', 'mkv']}
try:
return d[file_type]
except KeyError:
return []
get_ext('audio') # ['mp3', 'wav']
retourne une liste vide dans le cas où cette clé n'existe pas . quelle que soit la réponse la plus simple qui me vienne à l'esprit, pour une meilleure réponse, voir @timgeb answer.