Fix Dataset.map crash when first examples return None and later return dict (#7990)

Fixes #7990.

## Summary

`Dataset.map` crashed with `AttributeError: 'NoneType' object has no attribute 'write'` when the user's map function returned `None` for the first few examples and a `dict` (or `pa.Table` / DataFrame) for later ones.

The writer was initialized only when `i == 0` (or `i[0] == 0` in batched mode). If `update_data` flipped to `True` only on a later call, `i != 0`, so the writer was never initialized, and the next `writer.write(...)` raised.

This PR:

1. **Initializes the writer lazily** on the first non-`None` result (`if writer is None`), regardless of the example/batch index.
2. **Latches `update_data`** so it stays `True` once any non-`None` result has been seen. The previous walrus assignment (`update_data := (processed_inputs is not None)`) silently flipped the flag back to `False` on subsequent `None` returns, which caused the post-loop `if update_data: writer.finalize() ...` to no-op and silently dropped the writer's accumulated rows (the inverse `dict-then-None` pattern).
3. **Skips writes for `None` results** now that `update_data` no longer flips back.

## Reproduce BEFORE/AFTER yourself (copy-paste)

The only thing that changes between the two blocks is the checked-out git ref.

```bash
# --- BEFORE: origin/main, expect AttributeError ---
git fetch origin main
git checkout origin/main
python - <<'PY'
from datasets import Dataset
ds = Dataset.from_dict({"x": [1, 2, 3]})
def fn(example, idx):
    return None if idx < 2 else {"x": example["x"] * 10}
try:
    ds.map(fn, with_indices=True)
    print("NO CRASH")  # Expected: not reached
except AttributeError as e:
    print(f"REPRO: {e}")  # Expected: 'NoneType' object has no attribute 'write'
PY

# --- AFTER: this branch, expect no crash and correct output ---
git fetch origin pull/<PR>/head:fix
git checkout fix
python - <<'PY'
from datasets import Dataset
ds = Dataset.from_dict({"x": [1, 2, 3]})
def fn(example, idx):
    return None if idx < 2 else {"x": example["x"] * 10}
out = ds.map(fn, with_indices=True)
print(out["x"])  # Expected: [30]
PY
```

## What I ran locally

```
pytest tests/test_arrow_dataset.py -k "test_map or test_filter or test_class_encode_column"
# 63 passed, 10 skipped (Beam-related, pre-existing)
```

The new regression test `test_map_mixed_none_and_dict_returns` fails on `origin/main` with the exact `AttributeError` from the issue, and passes on this branch.

## Edge cases covered by the new test

| Pattern | Pre-fix | Post-fix |
|---|---|---|
| `None, None, dict` (the issue) | crash: `'NoneType' object has no attribute 'write'` | `[30]` |
| `dict, dict, None` | silently returns the **original** shard (writer never finalized because `update_data` flipped back to False) | `[10, 20]` |
| `dict, None, dict` (alternating) | crash on the second `dict` write because `update_data` was False at that point | `[10, 30]` |
| All `None` | unchanged | unchanged |
| All `dict` | unchanged | unchanged |
| Batched variants of the same | same crashes / silent drops | correct |

## Notes

- The lazy `if writer is None` init makes the location of the first dict-return irrelevant.
- The latch on `update_data` is necessary because the post-loop `if update_data: writer.finalize() ...` previously read whatever the **last** call set it to. A `dict, dict, None` sequence currently leaves `update_data == False` and silently drops the writer's accumulated rows. This is fixed here.
- No public API change.

---

🤖 Disclosure: This PR was authored with assistance from Claude (Anthropic), reviewed and tested by me. The reproducer was run end-to-end on this branch (`pytest tests/test_arrow_dataset.py -k test_map`), and the regression test was verified to fail on `origin/main` and pass on this branch.