Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

317
Views
Python3.8+ Prueba si un yaml es un subconjunto de otro

En resumen, estoy usando un archivo Yaml como configuración para los parámetros de algunas canalizaciones/funciones que estoy usando. En python, este es un diccionario anidado y los parámetros pueden ser una matriz / diccionarios. Sería útil iterar a través de todos los archivos de configuración y buscar aquellos en los que se especifica un subconjunto de valores, por ejemplo

 # toy example of all parameters a config file might have - param_a: 1 - param_b: - b1: 'a' - b2: [1,2,3]
 # want all configs with these values - param_a: 1 - param_b: - b2: [1,2,3]

Por supuesto, uno podría hacer recursividad en cada diccionario anidado, pero en lugar de reinventar la rueda, me preguntaba si existe una solución probada y verdadera.

He visto algunas preguntas relacionadas (buscando confirmar diccionarios idénticos) y aparece Deep Diff . Sin embargo, no está claro si al probar un subconjunto, DeepDiff devolverá todas las claves que faltan. ¿Pensamientos?

Por ahora estoy usando esto y asumiendo que yaml se cargó correctamente como un diccionario anidado

 def is_config_subset(truth, params): ''' Arguments: ---------- truth (dict): dictionary of parameters to compare to params (dict): dictionary of parameters to test Returns: ---------- result (bool) whether or not `params` is a subset of `truth` ''' if not type(truth) == type(params): return False for key, val in params.items(): if key not in truth: return False if type(val) is dict: if not is_config_subset(truth[key], val): return False else: if not truth[key] == val: return False return True print(is_config_subset({'a':1, 'b':2}, {'b':2})) print(is_config_subset({'a':1, 'b':2}, {'b':2, 'c':3})) print(is_config_subset({'a':1, 'b':2, 'c':[1,2,3]}, {'b':2, 'c':[1,2,3]})) print(is_config_subset({'a':1, 'b':2, 'c':[1,2,3]}, {'b':2, 'c':[1,2]})) print(is_config_subset({'a':1, 'b':2, 'c':[1,2,3]}, {'a':2, 'b':2})) True False True False False

Este es probablemente un ejemplo simplista y no funcionará en todos los casos.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Creo que la solución más simple, y quizás la más eficiente, sería definir su propia función auxiliar recursiva, algo así como is_subset . Dado que YAML y JSON tienen un formato muy similar, primero puede cargar sus datos YAML en un tipo de Python, ya sea una list o un dict , y pasarlos a una función recursiva, que realiza la verificación del subconjunto según un criterio predefinido.

Por ejemplo, aquí hay un ejemplo simple (en su mayoría completo) para comenzar.

 def is_subset(superset, o): """Check if `o` is subset of `superset`""" ss_type, o_type = type(superset), type(o) if ss_type != o_type: return False # now we know that both `superset` and `o` are the same type if o_type is dict: for o_key, o_value in o.items(): ss_value = superset.get(o_key) if not is_subset(ss_value, o_value): return False else: return True if o_type is list: # an empty list can be considered a subset if not o_type: return True # on other hand, if superset list is empty, we return false if not superset: return False first_o_type = type(o[0]) first_ss_type = type(superset[0]) if first_o_type != first_ss_type: return False if first_o_type is dict: merged_ss, merged_o = {}, {} for v in o: if type(v) is dict: # type check to be safe merged_o.update(v) # On Python 3.9+, the syntax would be: # merged_o |= v for v in superset: if type(v) is dict: # type check to be safe merged_ss.update(v) return is_subset(merged_ss, merged_o) elif first_o_type is list: for idx, o_value in enumerate(o): try: ss_value = superset[idx] except IndexError: return False if not is_subset(ss_value, o_value): return False else: return True else: # a list of simple types, like [1, 2, 3] for o_value in o: if o_value not in superset: return False else: return True # it's a simple type - not list or dict return superset == o

Tenga en cuenta que hay algunos casos extremos que no cubre, por ejemplo, list s en la configuración YAML con tipos de datos mixtos, como una lista de valores dict y str . Dejaré que usted decida cómo manejar esos casos extremos, en caso de que valga la pena cubrirlos también.

En cualquier caso, así es como usaría la función de ayuda que declaramos anteriormente:

 import yaml superset_config = yaml.safe_load(""" # toy example of all parameters a config file might have - param_a: 1 - param_b: - b1: 'a' - b2: [1,2,3] """) subset_config = yaml.safe_load(""" # want all configs with these values - param_a: 1 - param_b: - b2: [1,2,3] """) assert is_subset(superset_config, subset_config) subset_config[0]['param_c'] = 'test' assert not is_subset(superset_config, subset_config)
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!