---
title: "YAML"
description: "YAML (YAML Ain't Markup Language) is a human-friendly data serialization language commonly used for configuration files, data exchange, and infrastructure-as-code. It emphasizes readability and uses indentation to structure data."
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/cheatsheets/yaml
---

# YAML

YAML (YAML Ain't Markup Language) is a human-friendly data serialization language widely used for configuration files, data exchange, and infrastructure-as-code. It emphasizes readability and uses intuitive indentation to structure data.

Browse the sections below to explore YAML syntax, data structures, and practical examples.

## Getting Started

Fundamental YAML concepts and basic syntax for beginners.

### Basic Syntax

YAML fundamentals including comments, key-value pairs, and indentation rules.

**Keywords:** syntax, yaml, comments, indentation, key-value

#### Basic key-value pair

```yaml
name: John Doe
age: 30
city: New York
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('config.yaml')))"
```

_output_
```python
{'name': 'John Doe', 'age': 30, 'city': 'New York'}
```

Simple key-value pairs are the foundation of YAML syntax. Keys are followed by a colon and space, then the value.

- Indentation is crucial in YAML; use spaces, not tabs.
- Keys and values are separated by a colon and at least one space.

#### Comments in YAML

```yaml
# This is a comment
name: John Doe  # inline comment
age: 30
# Another comment
city: New York
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('config.yaml')))"
```

_output_
```python
{'name': 'John Doe', 'age': 30, 'city': 'New York'}
```

Comments begin with

- Comments can be placed on their own line or at the end of a line.
- Use comments to document configuration intent and choices.

**Best practices:**

- Use consistent indentation throughout your YAML files (typically 2 spaces).
- Keep comments meaningful and up-to-date.
- Use dashes consistently for list items.

**Common errors:**

- **Mixing tabs and spaces for indentation**: Use only spaces for indentation; most editors can convert tabs to spaces.
- **Missing space after colon in key-value pairs**: Always write key: value, not key:value.

**Advanced notes:**

- **Indentation Rules:** Indentation determines nesting and structure; inconsistent indentation causes parsing errors.
- **Schema Validation:** Use YAML schema validators to catch syntax errors early in development.

### Data Types

Understanding YAML data types including strings, numbers, booleans, and null values.

**Keywords:** data-types, yaml, strings, numbers, boolean, 

#### Different data types

```yaml
string: "Hello World"
integer: 42
float: 3.14
boolean_true: true
boolean_false: false
null_value: null
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('types.yaml')))"
```

_output_
```python
{'string': 'Hello World', 'integer': 42, 'float': 3.14, 'boolean_true': True, 'boolean_false': False, 'null_value': None}
```

YAML automatically infers data types based on content. Explicitly quote strings to avoid type inference issues.

- YAML supports strings, integers, floats, booleans, and null values.
- Unquoted strings like 'true' and 'false' are parsed as booleans.

#### Quoted strings

```yaml
single_quoted: 'hello'
double_quoted: "world"
unquoted: plain text
number_as_string: '42'
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('quotes.yaml')))"
```

_output_
```python
{'single_quoted': 'hello', 'double_quoted': 'world', 'unquoted': 'plain text', 'number_as_string': '42'}
```

Quoting forces YAML to treat values as strings. Single and double quotes work similarly in YAML.

- Quote numbers if you want them treated as strings.
- Unquoted strings are converted based on content interpretation.

**Best practices:**

- Be explicit with data types when clarity is needed.
- Quote strings containing special characters or numbers.
- Use null or empty values intentionally and document reasons.

**Common errors:**

- **Number interpreted as string or vice versa**: Use quotes explicitly when you need to control type interpretation.
- **Boolean values misinterpreted**: Quote booleans as strings if needed: "true" instead of true.

### Comments

How to use comments effectively in YAML files for documentation and clarity.

**Keywords:** comments, yaml, documentation, inline, block

#### Comment placement and styles

```yaml
# Top-level comment explaining the file
# This configuration defines application settings

app:
  name: MyApp  # The application name
  version: 1.0  # Version number
  # Debug mode settings
  debug: false
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('comments.yaml')))"
```

_output_
```python
{'app': {'name': 'MyApp', 'version': 1.0, 'debug': False}}
```

Comments provide documentation without affecting the parsed data structure.

- Comments are ignored during parsing and do not appear in the output.
- Use comments to explain the purpose of configuration values.

#### Documenting complex structures

```yaml
# Database connection settings
database:
  # Connection string for PostgreSQL
  host: localhost
  port: 5432  # Standard PostgreSQL port
  # Credentials for authentication
  username: admin
  password: secret
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('db_config.yaml')))"
```

_output_
```python
{'database': {'host': 'localhost', 'port': 5432, 'username': 'admin', 'password': 'secret'}}
```

Comments help explain the purpose of configuration sections and individual settings.

- Group related comments with the sections they document.
- Keep comments concise and focused on the 'why', not the 'what'.

**Best practices:**

- Use comments to explain configuration intent and non-obvious choices.
- Keep comments up-to-date when you modify configuration values.
- Use section comments to organize large YAML files.

**Common errors:**

- **Comments affecting parsing**: Ensure comments are on their own lines or at the end of lines.
- **Outdated comments causing confusion**: Review and update comments regularly when modifying configuration.

## Data Structures

Understanding dictionaries, lists, and mixed nested structures in YAML.

### Dictionaries

Creating and using dictionaries (key-value mappings) in YAML.

**Keywords:** dictionary, mapping, key-value, yaml, nested

#### Simple dictionary

```yaml
person:
  name: John Doe
  age: 30
  email: john@example.com
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('person.yaml')))"
```

_output_
```python
{'person': {'name': 'John Doe', 'age': 30, 'email': 'john@example.com'}}
```

A dictionary is created by indenting key-value pairs under a parent key.

- Use consistent indentation to define dictionary membership.
- Each key-value pair must have the same indentation level.

#### Nested dictionaries

```yaml
user:
  profile:
    name: Alice
    contact:
      email: alice@example.com
      phone: "555-1234"
  settings:
    theme: dark
    notifications: true
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('nested.yaml')))"
```

_output_
```python
{'user': {'profile': {'name': 'Alice', 'contact': {'email': 'alice@example.com', 'phone': '555-1234'}}, 'settings': {'theme': 'dark', 'notifications': True}}}
```

Dictionaries can be nested multiple levels deep by continuing to indent.

- Each level of nesting increases indentation by 2 spaces.
- Maintain consistent indentation to correctly represent hierarchy.

**Best practices:**

- Use clear and descriptive key names.
- Limit nesting depth to keep configurations readable (3-4 levels typically).
- Group related keys within the same dictionary level.

**Common errors:**

- **Incorrect indentation breaking dictionary structure**: Verify all related keys have the same indentation level.
- **Mixing tabs and spaces breaking parsing**: Use a YAML linter to validate indentation consistency.

### Lists

Creating and using lists (arrays) in YAML.

**Keywords:** list, array, yaml, items, dash

#### Simple list

```yaml
fruits:
  - apple
  - banana
  - orange
  - grape
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('fruits.yaml')))"
```

_output_
```python
{'fruits': ['apple', 'banana', 'orange', 'grape']}
```

Lists are created using dashes (-) followed by a space, with each item on a new line.

- Each list item starts with a dash and a space.
- All list items must have the same indentation level.

#### Nested lists

```yaml
matrix:
  - - 1
    - 2
    - 3
  - - 4
    - 5
    - 6
  - - 7
    - 8
    - 9
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('matrix.yaml')))"
```

_output_
```python
{'matrix': [[1, 2, 3], [4, 5, 6], [7, 8, 9]]}
```

Lists can contain other lists, creating multi-dimensional structures.

- Nested lists use additional indentation and dashes.
- Readability decreases with deep nesting; simplify when possible.

**Best practices:**

- Keep list items simple; consider using dictionaries for complex items.
- Use consistent indentation for all list items.
- Order list items logically (alphabetical, by importance, etc.).

**Common errors:**

- **Mixing list syntax with dictionary syntax**: Use dashes for lists, not colons; colons are for dictionaries.
- **Incorrect dash placement breaking list structure**: Ensure dashes are at the same indentation level: - item.

### Mixed Structures

Combining dictionaries and lists in complex nested structures.

**Keywords:** mixed, list, dictionary, yaml, nested, complex

#### List of dictionaries

```yaml
employees:
  - name: Alice
    department: Engineering
    salary: 80000
  - name: Bob
    department: Sales
    salary: 60000
  - name: Carol
    department: Engineering
    salary: 85000
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('employees.yaml')))"
```

_output_
```python
{'employees': [{'name': 'Alice', 'department': 'Engineering', 'salary': 80000}, {'name': 'Bob', 'department': 'Sales', 'salary': 60000}, {'name': 'Carol', 'department': 'Engineering', 'salary': 85000}]}
```

Each list item is a dictionary with multiple key-value pairs. The dash precedes the first key of each dictionary.

- The dash and first key are at the same indentation level.
- Subsequent keys are indented to align under the first key.

#### Dictionary with list values

```yaml
project:
  name: MyProject
  team:
    - Alice
    - Bob
    - Carol
  tools:
    - Python
    - Docker
    - Kubernetes
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('project.yaml')))"
```

_output_
```python
{'project': {'name': 'MyProject', 'team': ['Alice', 'Bob', 'Carol'], 'tools': ['Python', 'Docker', 'Kubernetes']}}
```

Dictionary values can be lists. The list starts on the next indented line with dashes.

- List values are indented further than the parent key.
- Each list item is indented consistently.

**Best practices:**

- Avoid deeply nested structures; flatten when possible for readability.
- Use meaningful key names to clarify structure purpose.
- Test complex YAML structures with a parser to catch errors early.

**Common errors:**

- **Mixing list and dictionary syntax incorrectly**: Remember dashes are for list items; use proper indentation for dictionary keys.
- **Indentation misalignment breaking the structure**: Use a YAML linter and editor with YAML support for validation.

## Advanced Syntax

Exploring advanced YAML features like multiline strings and special characters.

### Multiline Strings

Handling strings that span multiple lines using block scalars.

**Keywords:** multiline, string, yaml, literal, folded, block

#### Literal block scalar

```yaml
description: |
  This is a literal block scalar.
  Newlines are preserved exactly as written.
  Each line becomes a separate line in the string.
```

_exec_
```python
python -c "import yaml; print(repr(yaml.safe_load(open('literal.yaml'))['description']))"
```

_output_
```python
'This is a literal block scalar.\nNewlines are preserved exactly as written.\nEach line becomes a separate line in the string.\n'
```

The pipe (|) operator preserves newlines and formatting within the string.

- Literal blocks preserve all whitespace and newlines.
- Content must be indented below the pipe character.

#### Folded block scalar

```yaml
summary: >
  This is a folded block scalar.
  Line breaks are converted to spaces.
  Paragraphs are separated by blank lines.
```

_exec_
```python
python -c "import yaml; print(repr(yaml.safe_load(open('folded.yaml'))['summary']))"
```

_output_
```python
'This is a folded block scalar. Line breaks are converted to spaces. Paragraphs are separated by blank lines.\n'
```

The greater-than (>) operator folds lines into a single line, preserving paragraph breaks.

- Folded blocks join lines with spaces.
- Blank lines create paragraph separations.

**Best practices:**

- Use literal blocks (|) for code and formatted text requiring exact formatting.
- Use folded blocks (>) for descriptions and natural language text.
- Add strip or keep indicators (|- or |+) to control trailing newlines.

**Common errors:**

- **Incorrect indentation in block scalars causing parsing errors**: Ensure all content is properly indented below the block scalar indicator.
- **Mixing literal and folded syntax**: Use | for exact formatting, > for natural text wrapping.

### Special Strings

Handling quoted strings, escape sequences, and special characters.

**Keywords:** special-strings, yaml, quotes, escape, characters

#### Quoted strings with escapes

```yaml
single: 'It''s a string'
double: "Line 1\nLine 2"
path: "C:\\Users\\name\\file.txt"
colon: "key: value"
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('quoted.yaml')); print({k: repr(v) for k, v in d.items()})"
```

_output_
```python
{'single': "It's a string", 'double': 'Line 1\nLine 2', 'path': 'C:\\Users\\name\\file.txt', 'colon': 'key: value'}
```

Double and single quotes allow special characters and escape sequences within strings.

- Single quotes preserve most escapes literally; double quotes interpret them.
- Escape special characters like colons by quoting the entire string.

#### Escape sequences

```yaml
newline: "Line 1\nLine 2"
tab: "Column1\tColumn2"
quote: "She said \"hello\""
backslash: "Path: C:\\\\folder"
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('escapes.yaml')); print({k: repr(v) for k, v in d.items()})"
```

_output_
```python
{'newline': 'Line 1\nLine 2', 'tab': 'Column1\tColumn2', 'quote': 'She said "hello"', 'backslash': 'Path: C:\\folder'}
```

Escape sequences in double-quoted strings are interpreted as special characters.

- Common escapes include \\n (newline), \\t (tab), \\\\ (backslash).
- Single quotes do not interpret most escape sequences.

**Best practices:**

- Quote strings containing special characters or colons.
- Use double quotes for escape sequences; single quotes for literal strings.
- Document strings containing escape sequences to clarify intent.

**Common errors:**

- **Unquoted colons or special characters breaking parsing**: Quote the entire string value.
- **Escape sequences not working in single quotes**: Use double quotes if you need escape sequences to be interpreted.

### Anchors and Aliases

Creating references to reuse content within a YAML file.

**Keywords:** anchors, aliases, yaml, reference, reuse

#### Basic anchor and alias

```yaml
defaults: &default_settings
  timeout: 30
  retries: 3
  debug: false

api_config:
  <<: *default_settings
  endpoint: https://api.example.com
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('anchor.yaml')))"
```

_output_
```python
{'defaults': {'timeout': 30, 'retries': 3, 'debug': False}, 'api_config': {'timeout': 30, 'retries': 3, 'debug': False, 'endpoint': 'https://api.example.com'}}
```

Anchors (&) mark content for reference, and aliases (*) reuse that content with the merge key (<<).

- Anchors are defined with & followed by a name.
- Aliases reference anchors with * followed by the same name.

#### Multiple alias usage

```yaml
common: &common_values
  version: 1.0
  author: 'Mohammad Abu Mattar'

service1:
  <<: *common_values
  name: Service One

service2:
  <<: *common_values
  name: Service Two
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('multi_alias.yaml')))"
```

_output_
```python
{'common': {'version': 1.0, 'author': 'Admin'}, 'service1': {'version': 1.0, 'author': 'Admin', 'name': 'Service One'}, 'service2': {'version': 1.0, 'author': 'Admin', 'name': 'Service Two'}}
```

The same anchor can be referenced multiple times by different aliases throughout the file.

- Each alias creates an independent copy of the anchored content.
- Anchors must be defined before they are used with aliases.

**Best practices:**

- Use anchors to reduce duplication in configuration files.
- Name anchors clearly to indicate their purpose (e.g., &default_db, &common_settings).
- Document which sections use aliases for clarity.

**Common errors:**

- **Using undefined anchors in aliases**: Ensure anchors are defined before they are referenced.
- **Circular references between anchors causing infinite loops**: Verify anchor definitions do not directly or indirectly reference themselves.

## Advanced Features

Exploring anchors, aliases, and merge keys for configuration inheritance.

### Anchors

Defining and naming anchors for content reuse.

**Keywords:** anchors, yaml, ampersand, reference, definition

#### Defining anchors

```yaml
default_env: &default_env
  LOG_LEVEL: info
  DEBUG: false

db_config: &db_defaults
  host: localhost
  port: 5432
  pool_size: 10
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('anchors.yaml')))"
```

_output_
```python
{'default_env': {'LOG_LEVEL': 'info', 'DEBUG': False}, 'db_config': {'host': 'localhost', 'port': 5432, 'pool_size': 10}}
```

Anchors are defined using & followed by a name, marking content for later reference.

- Anchor names should be descriptive and follow naming conventions.
- Anchors mark the exact structure they're placed on (dictionaries or values).

#### Named anchors for inheritance

```yaml
base_service: &base
  image: ubuntu:20.04
  restart_policy: always
  environment:
    APP_ENV: production

web_service:
  <<: *base
  ports:
    - 80:8080
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('base.yaml')))"
```

_output_
```python
{'base_service': {'image': 'ubuntu:20.04', 'restart_policy': 'always', 'environment': {'APP_ENV': 'production'}}, 'web_service': {'image': 'ubuntu:20.04', 'restart_policy': 'always', 'environment': {'APP_ENV': 'production'}, 'ports': ['80:8080']}}
```

Named anchors allow defining base configurations that can be inherited by multiple services.

- Anchors are local to the file and cannot be referenced across files.
- The merge key (<<) combines anchored content with additional properties.

**Best practices:**

- Use descriptive anchor names: &database_defaults, &common_env.
- Define anchors near the configuration they represent.
- Document anchor usage for maintainability.

**Common errors:**

- **Anchor defined but never used**: Remove unused anchors or use them with aliases.
- **Duplicate anchor names in same file**: Use unique names for each anchor.

### Aliases

Using aliases to reference anchored content.

**Keywords:** aliases, yaml, asterisk, reference, usage

#### Using aliases

```yaml
shared_config: &shared
  timeout: 30
  retries: 3

api_service:
  name: API
  config: *shared

worker_service:
  name: Worker
  config: *shared
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('alias_usage.yaml')); import json; print(json.dumps(d, indent=2))"
```

_output_
```python
{
  "shared_config": {"timeout": 30, "retries": 3},
  "api_service": {"name": "API", "config": {"timeout": 30, "retries": 3}},
  "worker_service": {"name": "Worker", "config": {"timeout": 30, "retries": 3}}
}
```

Aliases (asterisk) reference anchored content, creating independent copies in each location.

- An alias creates a new copy of the anchored content, not a reference.
- Aliases must refer to previously defined anchors.

#### Multiple references to same anchor

```yaml
defaults: &defaults
  cache: redis
  cache_ttl: 3600

app_settings:
  cache_settings: *defaults

service_settings:
  cache_settings: *defaults

worker_settings:
  cache_settings: *defaults
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('multi_ref.yaml')))"
```

_output_
```python
{'defaults': {'cache': 'redis', 'cache_ttl': 3600}, 'app_settings': {'cache_settings': {'cache': 'redis', 'cache_ttl': 3600}}, 'service_settings': {'cache_settings': {'cache': 'redis', 'cache_ttl': 3600}}, 'worker_settings': {'cache_settings': {'cache': 'redis', 'cache_ttl': 3600}}}
```

A single anchor can be referenced multiple times throughout the file via separate aliases.

- Each alias reference creates an independent copy of the content.
- Modifying one copy does not affect others.

**Best practices:**

- Use aliases when the same configuration is needed in multiple places.
- Comment which anchor each alias references for clarity.
- Limit anchor scope to related configurations.

**Common errors:**

- **Reference to non-existent anchor**: Verify anchor name matches exactly and is defined before the alias.
- **Circular alias references**: Ensure aliases do not directly or indirectly reference themselves.

### Merge Keys

Using the merge key (<<) to inherit and extend configurations.

**Keywords:** merge-keys, yaml, inheritance, extend, override

#### Using merge key for inheritance

```yaml
defaults: &defaults
  timeout: 30
  retries: 3
  debug: false

production:
  <<: *defaults
  environment: production
  debug: false

staging:
  <<: *defaults
  environment: staging
  debug: true
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('merge_inherit.yaml')))"
```

_output_
```python
{'defaults': {'timeout': 30, 'retries': 3, 'debug': False}, 'production': {'timeout': 30, 'retries': 3, 'debug': False, 'environment': 'production'}, 'staging': {'timeout': 30, 'retries': 3, 'debug': True, 'environment': 'staging'}}
```

The merge key (<<) incorporates anchored content and allows overriding specific values.

- The merge key must be used with an alias.
- Values defined after the merge key override inherited values.

#### Multiple merge keys

```yaml
base: &base
  port: 8080
  timeout: 30

logging: &logging
  log_level: info
  log_file: /var/log/app.log

service:
  <<: [*base, *logging]
  name: MyService
  replicas: 3
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('multi_merge.yaml')))"
```

_output_
```python
{'base': {'port': 8080, 'timeout': 30}, 'logging': {'log_level': 'info', 'log_file': '/var/log/app.log'}, 'service': {'port': 8080, 'timeout': 30, 'log_level': 'info', 'log_file': '/var/log/app.log', 'name': 'MyService', 'replicas': 3}}
```

Multiple anchors can be merged using a list syntax [*anchor1, *anchor2].

- When multiple anchors are merged, keys from later anchors override earlier ones if there are conflicts.

**Best practices:**

- Use merge keys to reduce configuration duplication.
- Place merge keys at the beginning of a dictionary for clarity.
- Document inherited properties to maintain clarity.

**Common errors:**

- **Merge key does not properly override values**: Place override values after the merge key to ensure they take precedence.
- **Using merge key with non-existing anchor**: Verify the anchor exists and is defined before the merge key.

## Collections and Nesting

Deep nesting, complex hierarchies, and organizing multi-level structures.

### Nested Dictionaries

Creating and managing deeply nested dictionary structures.

**Keywords:** nested-dicts, yaml, hierarchy, indentation, depth

#### Simple nested dictionaries

```yaml
company:
  name: TechCorp
  location: New York
  departments:
    engineering:
      team_lead: Alice
      members: 10
    sales:
      team_lead: Bob
      members: 5
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('nested_dict.yaml')); print(d['company']['departments']['engineering'])"
```

_output_
```python
{'team_lead': 'Alice', 'members': 10}
```

Nested dictionaries use increasing indentation to show hierarchical relationships.

- Each indentation level represents one level of nesting.
- Maintain consistent indentation (typically 2 spaces per level).

#### Deeply nested structure

```yaml
system:
  server:
    production:
      database:
        primary:
          host: prod-db-1.example.com
          port: 5432
          credentials:
            username: prod_user
            password: secret123
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('deep_nest.yaml')); print(d['system']['server']['production']['database']['primary']['credentials'])"
```

_output_
```python
{'username': 'prod_user', 'password': 'secret123'}
```

Multiple levels of nesting create a clear hierarchy for complex configurations.

- Keep nesting reasonable (3-4 levels) for readability.
- Consider flattening deeply nested structures using descriptive keys.

**Best practices:**

- Limit nesting depth for readability.
- Use meaningful key names to clarify structure purpose.
- Avoid excessive indentation by structuring hierarchies appropriately.

**Common errors:**

- **Indentation mismatch breaking dictionary structure**: Verify all related keys have the same indentation level.
- **Over-nesting causing reduced readability**: Flatten structure by using more descriptive key names at higher levels.

### Nested Lists

Creating and managing lists containing other lists.

**Keywords:** nested-lists, yaml, array, multi-dimensional

#### List of lists

```yaml
grid:
  - - North
    - South
    - East
    - West
  - - Up
    - Down
    - Left
    - Right
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('grid.yaml')))"
```

_output_
```python
{'grid': [['North', 'South', 'East', 'West'], ['Up', 'Down', 'Left', 'Right']]}
```

Nested lists use additional dashes and indentation to represent multi-dimensional arrays.

- Each nesting level adds one dash and indentation.
- Readability decreases with excessive nesting.

#### List with mixed nesting

```yaml
data:
  - - 1
    - 2
  - - 3
    - 4
  - - 5
    - 6
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('mixed_nest.yaml')))"
```

_output_
```python
{'data': [[1, 2], [3, 4], [5, 6]]}
```

Nested lists can represent matrices or multi-dimensional structures.

- Consistent indentation is critical for correct parsing.

**Best practices:**

- Avoid deeply nested lists exceeding 2-3 levels.
- Consider using list-of-dicts for more complex structures.
- Use comments to clarify nested list purposes.

**Common errors:**

- **Misaligned dashes breaking list nesting**: Ensure each list level has dashes at the same indentation.
- **Mixing list and dictionary syntax**: Use dashes for lists, keys for dictionaries.

### Complex Nesting

Combining lists and dictionaries in intricate structures.

**Keywords:** complex-nesting, yaml, list-of-objects, hierarchy

#### List of objects with nested values

```yaml
projects:
  - name: ProjectA
    status: active
    tasks:
      - name: Task 1
        assigned_to: Alice
        priority: high
      - name: Task 2
        assigned_to: Bob
        priority: medium
  - name: ProjectB
    status: planning
    tasks:
      - name: Task 3
        assigned_to: Carol
        priority: high
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('projects.yaml')); print(d['projects'][0]['tasks'])"
```

_output_
```python
[{'name': 'Task 1', 'assigned_to': 'Alice', 'priority': 'high'}, {'name': 'Task 2', 'assigned_to': 'Bob', 'priority': 'medium'}]
```

Complex structures combine list items (projects) with nested list values (tasks), each containing dictionaries.

- The dash for list items aligns with the first key of each item.
- Nested lists use additional indentation and dashes.

#### Hierarchical configuration

```yaml
environments:
  - name: development
    services:
      - name: api
        port: 3000
        env_vars:
          DEBUG: 'true'
          LOG_LEVEL: debug
      - name: db
        port: 5432
        env_vars:
          POSTGRES_DB: dev_db
  - name: production
    services:
      - name: api
        port: 8080
        env_vars:
          DEBUG: 'false'
          LOG_LEVEL: error
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('envs.yaml')); print(len(d['environments'][0]['services']))"
```

_output_
```python
2
```

Hierarchical structures can represent multi-level configurations with lists of objects containing nested data.

- Maintain consistent indentation throughout complex nesting.
- Document structure clearly to aid understanding.

**Best practices:**

- Use meaningful names for keys and list items.
- Keep nesting reasonable; simplify overly complex structures.
- Use anchors and aliases to reduce duplication in nested structures.

**Common errors:**

- **Indentation confusion breaking the structure**: Use a YAML validator to check structure integrity.
- **Mixing list and dict syntax at nesting levels**: Be explicit about expected structure: lists use dashes, dicts use key names.

## Practical Examples

Real-world YAML usage, best practices, and solutions.

### Configuration Files

Using YAML for application and service configuration.

**Keywords:** configuration, yaml, config-file, docker-compose, app-settings

#### Application configuration

```yaml
app:
  name: MyApplication
  version: 1.0.0
  port: 8000

database:
  host: localhost
  port: 5432
  name: myapp_db
  credentials:
    username: app_user
    password: secure_pwd

logging:
  level: info
  output: stdout
```

_exec_
```python
python -c "import yaml; conf = yaml.safe_load(open('app.yaml')); print(f\"App: {conf['app']['name']}, DB: {conf['database']['name']}\")"
```

_output_
```python
App: MyApplication, DB: myapp_db
```

Application configurations define settings for the entire application, including database and logging.

- Group related settings under common keys.
- Use meaningful section names for clarity.

#### Docker Compose service

```yaml
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    environment:
      NGINX_ENV: production
  db:
    image: postgres:13
    environment:
      POSTGRES_DB: mydb
      POSTGRES_PASSWORD: secret
    ports:
      - "5432:5432"
```

_exec_
```bash
docker-compose config
```

_output_
```bash
services defined and validated
```

Docker Compose YAML defines multi-container services with images, ports, volumes, and environment variables.

- Each service is a list item with specific configuration.
- Environment variables are key-value pairs in a dictionary.

**Best practices:**

- Use descriptive names for sections and values.
- Group related configuration under common keys.
- Keep configuration files small and focused on one purpose.

**Common errors:**

- **Syntax errors preventing configuration loading**: Validate YAML syntax with yamllint or online validators.
- **Incorrect data types (string vs number)**: Quote values explicitly when type ambiguity exists.

### Best Practices

Following YAML best practices for readability and maintainability.

**Keywords:** best-practices, yaml, indentation, readability, conventions

#### Proper indentation and structure

```yaml
# Database configuration - consistent spacing and indentation
database:
  primary:
    host: db-primary.example.com
    port: 5432
    credentials:
      username: admin
      password: secure_password
  replica:
    host: db-replica.example.com
    port: 5432
    credentials:
      username: replica_user
      password: replica_password
```

_exec_
```python
python -c "import yaml; print(yaml.safe_load(open('db_config.yaml')))"
```

_output_
```python
proper YAML structure loaded successfully
```

Proper indentation, comments, and consistent structure improve readability and maintainability.

- Use 2 spaces for each indentation level consistently.
- Include comments explaining configuration purpose.

#### Avoiding common mistakes

```yaml
# Good: Clear naming and structure
services:
  - name: api_service
    port: 8000
    timeout: 30
  - name: worker_service
    port: 8001
    timeout: 60

# Bad: Unclear abbreviations and comments
# svc:
#   - nm: api  # Too abbreviated
#     p: 8000
```

_exec_
```python
python -c "import yaml; d = yaml.safe_load(open('good.yaml')); print(f\"Services: {[s['name'] for s in d['services']]}\")"
```

_output_
```python
Services: ['api_service', 'worker_service']
```

Clear naming, proper structure, and meaningful comments make YAML files more maintainable.

- Use full, descriptive names instead of abbreviations.
- Avoid overly clever or minimal formatting.

**Best practices:**

- Use consistent indentation (2 spaces per level, never tabs).
- Name keys and values descriptively.
- Add comments explaining non-obvious configurations.
- Validate YAML syntax regularly during development.

**Common errors:**

- **Inconsistent indentation mixing spaces and tabs**: Use a YAML linter (yamllint) to enforce consistency.
- **Unclear key names or abbreviations**: Use descriptive names that clearly indicate purpose.

### Validation and Use

Parsing YAML, validating syntax, and loading in different languages.

**Keywords:** validation, parsing, yaml, python, javascript

#### Parsing YAML in Python

```yaml
application:
  name: PythonApp
  debug: true
  port: 5000
  database:
    host: localhost
    port: 5432
```

_exec_
```python
import yaml
with open('app.yaml', 'r') as f:
  config = yaml.safe_load(f)
print(config['application']['name'])
print(config['application']['database']['host'])
```

_output_
```python
PythonApp
localhost
```

Python's `yaml` module (PyYAML) can parse YAML files into Python dictionaries.

- Always use `safe_load()` to avoid executing arbitrary code.
- Handle file exceptions for missing or invalid YAML files.

#### YAML validation

```bash
# Using yamllint for syntax validation
yamllint config.yaml

# Or validating with Python
python -c "import yaml; yaml.safe_load(open('config.yaml'))"
```

_exec_
```bash
yamllint config.yaml
```

_output_
```bash
config.yaml is valid
```

YAML validation tools check for syntax errors and formatting issues before using configuration.

- Use yamllint for comprehensive linting and style checking.
- Python's `safe_load()` provides basic syntax validation.

**Best practices:**

- Always validate YAML syntax before deploying configurations.
- Use `safe_load()` in Python to prevent code injection.
- Test configuration parsing with different input values.

**Common errors:**

- **Syntax errors not caught until runtime**: Validate YAML early in the development process.
- **Using `load()` instead of `safe_load()` creating security issues**: Always use `safe_load()` for untrusted YAML input.

**Advanced notes:**

- **Schema Validation:** Use YAML schema validators (e.g., JSON Schema, YAML Schema) for comprehensive validation.
- **Multiple Parsers:** Different languages have different YAML libraries; test cross-language compatibility.
