La forma más corta de obtener el primer elemento de `OrderedDict` en Python 3

¿Cuál es la forma más corta de obtener el primer artículo de OrderedDict en Python 3?

Mi mejor:

 list(ordered_dict.items())[0] 

Bastante largo y feo.

Puedo pensar en:

 next(iter(ordered_dict.items())) # Fixed, thanks Ashwini 

Pero no es muy autodescriptivo.

¿Alguna sugerencia mejor?

Prácticas de progtwigción para la lectura.

En general, si sientes que el código no se describe a sí mismo, la solución habitual es factorizarlo en una función bien nombrada:

 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)) 

Con esa función auxiliar , el código siguiente se vuelve muy legible:

 >>> extension = {'xml', 'html', 'css', 'php', 'xhmtl'} >>> one_extension = first(extension) 

Patrones para extraer un único valor de la colección

Las formas habituales de obtener un elemento de un conjunto , dict , OrderedDict , generador u otra colección no indexable son:

 for value in some_collection: break 

y:

 value = next(iter(some_collection)) 

Lo último es bueno porque la función next () le permite especificar un valor predeterminado si la colección está vacía o puede elegir permitirle que genere una excepción. La función next () también es explícita de que solicita el siguiente elemento.

Enfoque alternativo

Si realmente necesita indexación, segmentación y otros comportamientos de secuencia (como la indexación de múltiples elementos), es muy sencillo convertir a una lista con list(some_collection) o usar [itertools.islice()][2] :

 s = list(some_collection) print(s[0], s[1]) s = list(islice(n, some_collection)) print(s) 

Use popitem(last=False) , pero tenga en cuenta que elimina la entrada del diccionario, es decir, es destructiva.

 from collections import OrderedDict o = OrderedDict() o['first'] = 123 o['second'] = 234 o['third'] = 345 first_item = o.popitem(last=False) >>> ('first', 123) 

Para más detalles, eche un vistazo al manual de colecciones . También funciona con Python 2.x.

Subclasificar y agregar un método a OrderedDict sería la respuesta a los problemas de claridad:

 >>> o = ExtOrderedDict(('a',1), ('b', 2)) >>> o.first_item() ('a', 1) 

La implementación de ExtOrderedDict :

 class ExtOrderedDict(OrderedDict): def first_item(self): return next(iter(self.items())) 

El código que se puede leer deja el OrderedDict sin cambios y no genera innecesariamente una lista potencialmente grande solo para obtener el primer elemento:

 for item in ordered_dict.items(): return item 

Si order_dict está vacío, Ninguno se devolverá implícitamente.

Una versión alternativa para usar dentro de un tramo de código:

 for first in ordered_dict.items(): break # Leave the name 'first' bound to the first item else: raise IndexError("Empty ordered dict") 

El código de Python 2.x correspondiente al primer ejemplo anterior necesitaría usar iteritems () en su lugar:

 for item in ordered_dict.iteritems(): return item 

La solución recomendada next(iter(s)) funciona para el caso específico cuando desea extraer el primer valor de un iterable. Si su iterable es de longitud conocida, puede generalizar para extraer el valor 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') 

Esta es una forma clara de aclarar la intención, admitir índices negativos y manejar errores cuando se proporciona un índice incorrecto. Ejemplo de uso con 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 

Primer registro

 [key for key, value in ordered_dict][0] 

Último registro :

 [key for key, value in ordered_dict][-1] 
 first = next #