es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Python 3.10 coincidencia de patrones (PEP 634) – comodín en cadena

Tengo una larga lista de objetos JSON que quiero analizar dependiendo del inicio de una de las claves, y simplemente poner un comodín para el resto. Muchas de las claves son similares, como “matchme-foo” y “matchme-bar”. Hay un comodín incorporado, pero solo se usa para valores completos, como un else.

Puede que esté pasando por alto algo, pero no puedo encontrar una solución en ninguna parte de la propuesta:

https://docs.python.org/3/whatsnew/3.10.html#pep-634-structural-pattern-matching

También un poco más al respecto en PEP-636:

https://www.python.org/dev/peps/pep-0636/#going-to-the-cloud-mappings

Mis datos se ven así:

data = [{
“id” : “matchme-foo”,
“message”: “hola, este es un mensaje”,
},{
“id” : “matchme-bar”,
“message”: “adiós”,
},{
“id” : “otroid”,
“message”: “evento completamente diferente”
}, …]

Quiero hacer algo que pueda coincidir con el id sin tener que hacer una larga lista de |.

Algo como esto:

for event in data:
match event:
case {‘id’:’matchme-*’}: # Coincidir con todos los ‘matchme-‘ sin importar lo que venga después
log.INFO(event[‘message’])
case {‘id’:’otroid’}:
log.ERROR(event[‘message’])

Es una adición relativamente nueva a Python, por lo que aún no hay muchas guías sobre cómo usarlo.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Basado en la propuesta actual para el emparejamiento de patrones estructurales en Python 3.10, no parece haber una solución incorporada para la coincidencia de comodines en las claves de objetos JSON. Sin embargo, es posible utilizar el emparejamiento de patrones con una función de emparejamiento personalizada para lograr esta funcionalidad deseada.

    Un posible enfoque es definir una función de emparejamiento personalizada que verifique el inicio de la clave en el objeto JSON con respecto a un determinado patrón. Por ejemplo:

    from typing import Tuple
    import re
    
    def key_starts_with(pattern: str, keyval_pair: Tuple[str, str]) -> bool:
        """"Empareja el inicio de la clave en el par clave-valor contra un patrón dado."""
        key, _ = keyval_pair
        return re.match(pattern, key) is not None
    

    Luego, esta función de emparejamiento personalizada se puede usar en la declaración de emparejamiento de patrones para emparejar las claves deseadas en el objeto JSON:

    for event in data:
        match event.items():
            case key_starts_with('matchme-', (key, value)):
                log.INFO(event['message'])
            case key == 'anotherid':
                log.ERROR(event['message'])
    

    En este ejemplo, la función key_starts_with se utiliza como un emparejador para el primer caso para emparejar todas las claves que comienzan con "matchme-". La condición key == 'anotherid' en el segundo caso coincide solo con la clave "anotherid" exactamente.

    Si bien este enfoque requiere definir una función de emparejamiento personalizada, proporciona la funcionalidad deseada de emparejar claves en el objeto JSON basado en su inicio sin tener que enumerar todas las posibles variaciones con operadores |.

Comments are closed.