---
id: infer_provincia_from_cp_py_core
name: infer_provincia_from_cp
kind: function
lang: py
domain: core
version: "1.0.0"
purity: pure
signature: "def infer_provincia_from_cp(rows: list[dict], cp_col: str = \"codigo_postal\", prov_col: str = \"provincia\") -> list[str | None]"
description: "Infiere la provincia correcta de cada fila basandose en el CP dominante por provincia. Calcula top-2 prefijos de CP por provincia; si el CP de la fila pertenece a ese top-2 usa el real, si no usa el dominante. Stdlib puro, sin pandas."
tags: [string, normalization, spain, geography, postal-code, inference]
uses_functions: [cp_provincia_es_py_core]
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: ["collections.Counter"]
example: |
  from infer_provincia_from_cp import infer_provincia_from_cp
  rows = [
      {"codigo_postal": "28001", "provincia": "Madrid"},
      {"codigo_postal": "28010", "provincia": "Madrid"},
      {"codigo_postal": "99999", "provincia": "Madrid"},
  ]
  infer_provincia_from_cp(rows)
  # ["Madrid", "Madrid", "Madrid"]
tested: true
tests: ["inferencia con cp dominante madrid", "fila con cp fuera de top2 usa dominante", "fila sin provincia retorna None"]
test_file_path: "python/functions/core/tests/test_infer_provincia_from_cp.py"
file_path: "python/functions/core/infer_provincia_from_cp.py"
params:
  - name: rows
    desc: "Lista de dicts. Cada dict debe tener al menos cp_col (codigo postal) y prov_col (provincia declarada)."
  - name: cp_col
    desc: "Nombre de la clave del codigo postal en cada dict. Por defecto 'codigo_postal'."
  - name: prov_col
    desc: "Nombre de la clave de la provincia en cada dict. Por defecto 'provincia'."
output: "Lista de strings o None con la provincia inferida para cada fila, en el mismo orden que rows. None cuando la provincia o el CP de la fila es None o la provincia no tiene datos suficientes."
source_repo: "internal:footprint_aurgi"
source_license: "internal-aurgi"
source_file: "aurgi_mapas/generar_pdf_reporte.py"
---

## Ejemplo

```python
from infer_provincia_from_cp import infer_provincia_from_cp

rows = [
    {"codigo_postal": "28001", "provincia": "Madrid"},
    {"codigo_postal": "28010", "provincia": "Madrid"},
    {"codigo_postal": "41001", "provincia": "Madrid"},  # CP Sevilla pero provincia Madrid
]
result = infer_provincia_from_cp(rows)
# ["Madrid", "Madrid", "Madrid"]
# El tercer CP (41) no esta en top-2 de Madrid (28), asi que usa el dominante (28 -> Madrid)
```

## Notas

Funcion pura. Usa `cp_provincia_es` del mismo dominio para el lookup final.
Adaptada de `add_provincia_poliza_correcta` en `aurgi_mapas/generar_pdf_reporte.py`,
eliminando la dependencia de pandas y generalizando las columnas por parametro.
El algoritmo mantiene la semantica original: top-2 prefijos por provincia, con
fallback al dominante cuando el CP de la fila no encaja en ese top-2.
