¿Por qué la lista no tiene un método seguro "get" como el diccionario?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
¿Por qué la lista no tiene un método seguro "get" como el diccionario?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
l[10:11]
su lugar: en lugar del[10]
, por ejemplo. () La sublista tendrá el elemento deseado si existe).get
. Sería el equivalentel[i] if i < len(l) else default
, pero más legible, más conciso, y permitiríai
ser una expresión sin tener que recalcularloNone
si no existiera. Hubiera sido bueno decirlox = expensive().get(0, None)
para no tener que poner el inútil retorno de costoso en una variable temporal.Respuestas:
En última instancia, es probable que no tenga un
.get
método seguro porque adict
es una colección asociativa (los valores están asociados con los nombres) donde es ineficiente verificar si una clave está presente (y devolver su valor) sin lanzar una excepción, mientras que es super trivial para evitar excepciones al acceder a elementos de la lista (ya que ellen
método es muy rápido). El.get
método le permite consultar el valor asociado con un nombre, no acceder directamente al elemento 37 en el diccionario (que sería más parecido a lo que está pidiendo de su lista).Por supuesto, puede implementar esto fácilmente usted mismo:
Incluso podría incluirlo en el
__builtins__.list
constructor__main__
, pero eso sería un cambio menos generalizado ya que la mayoría del código no lo usa. Si solo quisiera usar esto con listas creadas por su propio código, simplemente podría subclasificarlist
y agregar elget
método.fuente
list
.get
resuelve un problema que las listas no tienen, una forma eficiente de evitar excepciones al obtener datos que pueden no existir. Es súper trivial y muy eficiente saber qué es un índice de lista válido, pero no hay una forma particularmente buena de hacerlo para los valores clave en un diccionario.O(1)
. No será tan rápido en términos crudos como la comprobaciónlen
, pero desde el punto de vista de la complejidad, todos lo sonO(1)
. La respuesta correcta es la típica de uso / semántica ...dict
es solo el mejor caso O (1), no todos los casos..get()
o tiene problemas en otra parte de su código (o entorno). El punto de usar tal método es la legibilidad del código. La técnica "vainilla" requiere cuatro líneas de código en cada lugar que se necesita hacer. La.get()
técnica solo requiere uno y se puede encadenar fácilmente con llamadas a métodos posteriores (por ejemplomy_list.get(2, '').uppercase()
).Esto funciona si quieres el primer elemento, como
my_list.get(0)
Sé que no es exactamente lo que pediste, pero podría ayudar a otros.
fuente
next(iter(my_list[index:index+1]), 'fail')
Permite cualquier índice, no sólo 0. o menos FP, pero sin duda más Pythonic, y es casi seguro que sea más legible:my_list[index] if index < len(my_list) else 'fail'
.Probablemente porque simplemente no tenía mucho sentido para la semántica de listas. Sin embargo, puede crear fácilmente el suyo subclasificando.
fuente
get
método. La legibilidad cuenta. Y la legibilidad sufre con cada clase adicional innecesaria. Simplemente use eltry / except
enfoque sin crear subclases.En lugar de usar .get, usar esto debería estar bien para las listas. Solo una diferencia de uso.
fuente
.get
método (excepto que no estoy seguro de cómo explicarías lo que significaba el índice en este caso, o por qué alguna vez fallaría).lst[i] if -len(lst) <= i < len(l) else 'fail'
Prueba esto:
fuente
Créditos a jose.angel.jimenez
Para los fanáticos de "oneliner" ...
Si desea el primer elemento de una lista o si desea un valor predeterminado si la lista está vacía, intente:
devoluciones
a
y
devoluciones
default
Ejemplos para otros elementos ...
Con reserva predeterminada ...
Probado con
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
fuente
value, = liste[:1] or ('default',)
. Parece que necesitas los paréntesis.Lo mejor que puede hacer es convertir la lista en un dict y luego acceder a ella con el método get:
fuente
zip range len
, uno podría usardict(enumerate(my_list))
Así que investigué un poco más sobre esto y resultó que no hay nada específico para esto. Me emocioné cuando encontré list.index (valor), devuelve el índice de un elemento específico, pero no hay nada para obtener el valor en un índice específico. Entonces, si no desea utilizar la solución safe_list_get, que creo que es bastante buena. Aquí hay algunas declaraciones de 1 liner if que pueden hacer el trabajo por usted dependiendo del escenario:
También puede usar None en lugar de 'No', lo que tiene más sentido .:
Además, si solo desea obtener el primer o el último elemento de la lista, esto funciona
También puede convertirlos en funciones, pero aún así me gustó la solución de excepción IndexError. Experimenté con una versión
safe_list_get
simplificada de la solución y la hice un poco más simple (no predeterminada):No se ha comparado para ver qué es lo más rápido.
fuente
list
subclasificándolo. De esa forma, el constructor puede tomar unalist
o cualquier cosa que se comporte como una lista, y la nueva instancia se comporte como unalist
. Vea la respuesta de Keith a continuación, que debería ser la aceptada en mi humilde opinión.dict.get()
devolver un valor predeterminado de una referencia de índice de lista en lugar de tener que atraparloIndexError
? Entonces, realmente se trata de la función de idioma / biblioteca (y no de OOP vs contexto FP). Además, uno probablemente tiene que calificar su uso de 'pythonic' como quizás WWGD (como su desdén por FP Python es bien conocido) y no necesariamente solo satisfacer PEP8 / 20.el = x[4] if len(x) == 4 else 'No'
- quieres decirlen(x) > 4
?x[4]
está fuera de límites silen(x) == 4
.Los diccionarios son para búsquedas. Tiene sentido preguntar si existe una entrada o no. Las listas generalmente se repiten. No es común preguntar si existe L [10] sino más bien si la longitud de L es 11.
fuente
Básicamente, su caso de uso solo es relevante cuando se realizan matrices y matrices de una longitud fija, para que sepa cuánto tiempo tienen de antemano. En ese caso, normalmente también los crea antes de rellenarlos con Ninguno o 0, de modo que de hecho cualquier índice que usará ya existe.
Se podría decir esto: necesito .get () en los diccionarios con bastante frecuencia. Después de diez años como programador a tiempo completo, no creo que alguna vez lo haya necesitado en una lista. :)
fuente
'lalala' in url.split('/')[2:]
. Pero el problema con su solución aquí es que solo mira el segundo elemento. ¿Qué pasa si la URL es '/ monkeybonkey / lalala'? Obtendrá unTrue
mensaje aunque la URL no sea válida.