Search code examples
pythonyamlpyyaml

Query yaml file with python


I have a yaml file which was generated by the pyqtgraph library for the arrangement of the docks which looks like the following:

float: []
main: !!python/tuple
- vertical
- - !!python/tuple
    - vertical
    - - !!python/tuple
        - horizontal
        - - !!python/tuple
            - dock
            - NameOfDock1
            - true
          - !!python/tuple
            - dock
            - NameOfDock2
            - true
          - !!python/tuple
            - dock
            - NameOfDock3
            - true
          - !!python/tuple
            - dock
            - NameOfDock4
            - true
          - !!python/tuple
            - dock
            - NameOfDock5
            - true
        - sizes:
          - 174
          - 174
          - 433
          - 388
          - 401
      - !!python/tuple
        - horizontal
        - - !!python/tuple
            - dock
            - NameOfDock6
            - true
          - !!python/tuple
            - dock
            - NameOfDock7
            - true
        - sizes:
          - 397
          - 1185
    - sizes:
      - 313
      - 93
  - !!python/tuple
    - horizontal
    - - !!python/tuple
        - dock
        - NameOfDock8
        - true
      - !!python/tuple
        - dock
        - NameOfDock9
        - true
    - sizes:
      - 791
      - 791
  - !!python/tuple
    - horizontal
    - - !!python/tuple
        - dock
        - NameOfDock10
        - true
      - !!python/tuple
        - dock
        - NameOfDock11
        - true
    - sizes:
      - 1318
      - 264
- sizes:
  - 410
  - 80
  - 80

Is there an elegant way to query this kind of yaml file to get a list of all the names of the docks ([NameOfDock1, NameOfDock2, NameOfDock3, NameOfDock4, ...]). I heard of the yaql library but I would prefer a builtin solution if it's possible but it's also welcome if easy to implement. Thanks in advance for suggestions!

PS: I think it would be elegant to have a query like: if in every python tuple there exist the "dock" element than append the next element to the dock_list but I'm not sure how to implement it.


Solution

  • Your structure seems to be nodes where each node is either vertical, horizontal or dock. The first two have children as second item, the dock has a name. The simplest way to get all dock names would therefore be a fold:

    # get_docks returns a list of dock names in the given node
    def get_docks(data):
      # if it's a dock node, return a list with the dock's name as single item
      return [ data[1] ] if data[0] == "dock" else [
          dock for item in data[1] for dock in get_docks(item) ]
      # if not, call get_docks on each list item in the node's children and
      # accumulate the dock names in a single list
    
    print(get_docks(config))
    

    This will give you

    ['NameOfDock1', 'NameOfDock2', 'NameOfDock3', 'NameOfDock4', 'NameOfDock5', 'NameOfDock6', 'NameOfDock7', 'NameOfDock8', 'NameOfDock9', 'NameOfDock10', 'NameOfDock11']