Quel est le moyen le plus rapide d’obtenir le premier élément de OrderedDict
en Python 3?
Mon meilleur:
list(ordered_dict.items())[0]
Assez long et moche.
Je peux penser à:
next(iter(ordered_dict.items())) # Fixed, thanks Ashwini
Mais ce n'est pas très auto-descriptif.
De meilleures suggestions?
En général, si vous pensez que le code n'est pas auto-descriptif, la solution habituelle consiste à le factoriser en une fonction bien nommée:
def first(s):
'''Return the first element from an ordered collection
or an arbitrary element from an unordered collection.
Raise StopIteration if the collection is empty.
'''
return next(iter(s))
Avec cette fonction helper , le code suivant devient très lisible:
>>> extension = {'xml', 'html', 'css', 'php', 'xhmtl'}
>>> one_extension = first(extension)
Les méthodes habituelles pour obtenir un élément à partir d'un set, dict, OrderedDict, d'un générateur ou d'une autre collection non indexable sont les suivantes:
for value in some_collection:
break
et:
value = next(iter(some_collection))
Ce dernier est agréable car la fonction next () vous permet de spécifier une valeur par défaut si la collection est vide ou vous pouvez choisir de la laisser déclencher une exception. La fonction next () indique également explicitement qu'elle demande l'élément suivant.
Si vous avez réellement besoin d'indexation et de découpage et d'autres comportements de séquence (tels que l'indexation de plusieurs éléments), il est simple de convertir une liste avec list(some_collection)
ou d'utiliser [itertools.islice()][2]
:
s = list(some_collection)
print(s[0], s[1])
s = list(islice(n, some_collection))
print(s)
Utilisez popitem(last=False)
, mais gardez à l’esprit que cela supprime l’entrée du dictionnaire, c’est-à-dire qu’elle est destructive.
from collections import OrderedDict
o = OrderedDict()
o['first'] = 123
o['second'] = 234
o['third'] = 345
first_item = o.popitem(last=False)
>>> ('first', 123)
Pour plus de détails, consultez le manuel sur collections . Cela fonctionne aussi avec Python 2.x.
Sous-classer et ajouter une méthode à OrderedDict
serait la réponse aux problèmes de clarté:
>>> o = ExtOrderedDict(('a',1), ('b', 2))
>>> o.first_item()
('a', 1)
L'implémentation de ExtOrderedDict
:
class ExtOrderedDict(OrderedDict):
def first_item(self):
return next(iter(self.items()))
Premier enregistrement :
[key for key, value in ordered_dict][0]
Dernier enregistrement :
[key for key, value in ordered_dict][-1]
La solution recommandée next(iter(s))
fonctionne dans le cas spécifique où vous souhaitez extraire la valeur first d'une valeur itérable. Si votre itérable est de longueur connue, vous pouvez généraliser pour extraire la valeur n th:
def get_nth_item(it, n=0):
if n < 0:
n += len(it)
for index, item in enumerate(it):
if index == n:
return item
raise IndexError(f'Iterable index {n} out of range')
C'est un moyen clair de clarifier l'intention, en prenant en charge les index négatifs et qui gèrent les erreurs lorsqu'un index incorrect est fourni. Exemple d'utilisation avec OrderedDict
:
from collections import OrderedDict
od = OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')])
get_nth_item(od.items(), n=0) # (1, 'a')
get_nth_item(od.items(), n=-1) # (3, 'c')
get_nth_item(od.items(), n=3) # IndexError: Iterable index 3 out of range
Un code lisible laisse le OrderedDict inchangé et ne génère pas inutilement une liste potentiellement longue juste pour obtenir le premier élément:
for item in ordered_dict.items():
return item
Si command_dict est vide, aucun ne sera retourné implicitement.
Une version alternative à utiliser dans une portion de code:
for first in ordered_dict.items():
break # Leave the name 'first' bound to the first item
else:
raise IndexError("Empty ordered dict")
Le code Python 2.x correspondant au premier exemple ci-dessus devrait utiliser iteritems () à la place:
for item in ordered_dict.iteritems():
return item