¿Obteniendo solo elemento de una lista de un solo elemento en Python?

83

Cuando se sabe que una lista de Python siempre contiene un solo elemento, ¿hay alguna forma de acceder a ella que no sea:

mylist[0]

Puede preguntar: '¿Por qué querrías hacerlo?'. Curiosidad sola. Parece haber una forma alternativa de hacer todo en Python.

Pyderman
fuente
5
Puede haber alternativas, pero generalmente solo hay una forma obvia de hacerlo y, en este caso, parece que ya la ha encontrado.
ekhumoro
si siempre contiene un solo elemento, ¿quizás a listno es el mejor tipo de datos?
David Zemens
13
@ekhumoro: De hecho, soy parcial al método de desempaquetado de secuencias, porque verifica la suposición de que la secuencia solo tiene un elemento. mylist[0]tiene éxito cuando tiene al menos un elemento, pero no se queja si realmente tiene 30 elementos. singleitem, = mylistverifica que tienes exactamente un elemento, ni más ni menos.
ShadowRanger
1
@ShadowRanger. La pregunta es explícitamente sobre cómo acceder al único elemento de una lista que ya se sabe que contiene un solo elemento.
ekhumoro
6
@ekhumoro: Sin desacuerdo. Simplemente prefiero programar a la defensiva, para que las violaciones de los requisitos no pasen silenciosamente (seguro que falla, pero falla en voz alta, lo cual es mucho más fácil de identificar y corregir que las malas conductas sutiles). Si tuviera una moneda de cinco centavos por cada vez que algún comportamiento "conocido" en el código de producción resultara estar completamente equivocado ... Bueno, probablemente no sería rico , pero podría llevar a la familia a un lugar realmente agradable. cena.
ShadowRanger

Respuestas:

123

Secuencia de desembalaje:

singleitem, = mylist
# Identical in behavior (byte code produced is the same),
# but arguably more readable since a lone trailing comma could be missed:
[singleitem] = mylist

Uso explícito del protocolo iterador:

singleitem = next(iter(mylist))

Pop destructivo:

singleitem = mylist.pop()

Índice negativo:

singleitem = mylist[-1]

Establecer mediante iteración única for(porque la variable de bucle permanece disponible con su último valor cuando termina un bucle):

for singleitem in mylist: break

Muchos otros (combinando o variando bits de los anteriores, o dependiendo de la iteración implícita), pero entiendes la idea.

ShadowRanger
fuente
6
No es digno de ser incluido en la respuesta principal debido a una locura desenfrenada: Desempaquetado de parámetros en la función de un solo argumento (hecho como lambda anónimo que devuelve el valor de máxima estupidez):singleitem = (lambda x: x)(*mylist)
ShadowRanger
6
El primero es único en el sentido de que también aumenta si la lista contiene más de un elemento.
Neil G
7
El primero también se puede escribir como [singleitem] = mylist.
Carsten S
@NeilG: Lamentablemente, no es del todo único; la versión de "locura desenfrenada" en los comentarios también lo hace (al igual que el desempaquetado a través de la sintaxis de lista, aunque en realidad es idéntico al primer ejemplo en cuanto al comportamiento). Me siento un poco sucio ahora.
ShadowRanger
1
@CarstenS: Por lo general, desapruebo el uso []para el desempaquetado de secuencias ( for [i, x] in enumerate(iterable):me vuelve loco), pero sí, en el caso de desempaquetar un solo valor, la coma final se puede perder fácilmente, y el uso de corchetes es justificable por razones de legibilidad. Lo agregué a la respuesta. ¡Gracias!
ShadowRanger
20

Agregaré que la more_itertools biblioteca tiene una herramienta que devuelve un elemento de un iterable.

from more_itertools import one


iterable = ["foo"]
one(iterable)
# "foo"

Además, more_itertools.onegenera un error si el iterable está vacío o tiene más de un elemento.

iterable = []
one(iterable)
# ValueError: not enough values to unpack (expected 1, got 0)

iterable = ["foo", "bar"]
one(iterable)
# ValueError: too many values to unpack (expected 1)

more_itertools es un paquete de terceros > pip install more-itertools

pylang
fuente