Pregunta

De acuerdo Digamos que tengo una lista, y quiero comprobar si existe esa lista dentro de otra lista. Puedo hacer que al hacer esto:

all(value in some_map for value in required_values)

Lo que funciona bien, pero digamos que yo quiero a la lanzar una excepción cuando un valor requerido no está presente, con el valor que se encuentra. ¿Cómo puedo hacer que el uso de la lista de la comprensión?

Estoy más o menos curioso, todas las señales parecen apuntar a ninguna.

editar Argh me refería a esto:

for value in required_values:
 if value not in some_map:
  raise somecustomException(value)

En cuanto a los que no puedo ver cómo puedo encontrar el valor donde se produjo el error

¿Fue útil?

Solución

  

Digamos que quiero al lanzar una excepción cuando un valor requerido no está presente, con el valor que se encuentra. ¿Cómo puedo hacer que el uso de lista por comprensión?

Las listas por comprensión son una forma concisa sintácticamente para crear una lista basada en alguna lista existente; son no una forma de propósito general de escribir cualquier for bucle en una sola línea. En este ejemplo, usted no está realmente la creación de una lista, por lo que no tiene ningún sentido utilizar una lista por comprensión.

Otros consejos

No se puede utilizar aumento en una lista por comprensión. Se puede comprobar por sí mismo mirando la gramática en el lenguaje Python de referencia .

Puede sin embargo, invocar una función que genera una excepción para usted.

Si no desea considerar duplicados y los valores se hashable, utilizar conjuntos. Son más fáciles, más rápidos, y pueden extraer "todos" los elementos que faltan en una sola operación:

required_values = set('abc') # store this as a set from the beginning
values = set('ab')
missing = required_values - values
if missing:
    raise SomeException('The values %r are not in %r' % 
                        (missing, required_values))

Otro (feo) posibilidad sería la función error_on_false:

def error_on_false(value)
    if value:
        return value
    else:
        raise Exception('Wrong value: %r' % value)

if all(error_on_false(value in some_map) for value in required_values):
    continue_code()
    do_something('...')

Eso es feo. Que haría uso de la set lugar.

Me preguntaba sobre esta noche. Mi caso de uso está interactuando sobre una lista de objetos y levantando un error cuando el objeto no era de un tipo específico. Mi solución es utilizar un generador.

def iter_my_class(my_class_list):
    for c in my_class_list:
        if not isinstance(c, MyClass):
            raise ValueError('Expected MyClass')
        yield c

A continuación, se utiliza como

classes = [c for c in iter_my_class(my_class_list)]

escribí esto en mi teléfono. Si que se ejecuta sin errores a todos me debes una cerveza.

Por supuesto que puede hackear algo juntos, pero no es particularmente fácil de leer.

(_ for _ in ()) define un generador, desde donde se puede utilizar el método throw plantear ninguna excepción que desea.

all((_ for _ in ()).throw(somecustomException(value)) for value in required_values if value not in some_map)

Una vez dicho esto, la legibilidad de lado, no tiene sentido utilizar una lista por comprensión a menos que estés realmente va a utilizar la lista. Esto podría tener más sentido como algo parecido a:

map_values=[some_map[value] if value in some_map else (_ for _ in ()).throw(somecustomException(value)) for value in required_values]

Pero incluso entonces es probable que tenga más sentido para controlar la excepción fuera del bucle. Si desea elevar una excepción personalizada por alguna razón que sólo puede coger el KeyError y elevar su propia excepción.

try:
    found_values=[some_map[value] for value in required_values]
except KeyError as e:
    raise somecustomException(e.args[0])

Aunque creo que el uso de conjuntos (como el ejemplo de nosklo) es mejor, se podría hacer algo tan simple como esto:

def has_required(some_map, value):
  if not value in some_map:
    raise RequiredException('Missing required value: %s' % value)

all(has_required(some_map, value) for value in required_values)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top