ENH: Renaming and changing dtypes using single dictionary
#### Is your feature request related to a problem?

When cleaning and preparing different datasets in pandas, I often find myself needing to rename and specify the dtypes of columns. When I have a large number of columns to rename and specify data types for, I like to use the current dictionary syntax that works with `DataFrame.rename` and `DataFrame.astype` and is often supported for `dtype` kwargs, for example in `pandas.read_csv`:

```python
renames = {
    "originalColumnA": "column_a",
    "ORIGinal  Column B": "column_b",
    "  Original COLUMN C": "column_c",
}

dtypes = {
    "originalColumnA": "int32",
    "ORIGinal  Column B": "string",
    "  Original COLUMN C": "category",
}

df = pandas.read_csv("data.csv", dtype=dtypes)
df = df.rename(columns=renames)

# Or without read_csv ...
df = pandas.read_csv("data.csv")
df = df.astype(dtype=dtypes)
df = df.rename(columns=renames)
```

The current syntax means you have to define two different dictionaries with very similar or often identical keys. When dealing with a lot of columns this can be non-ideal to maintain (e.g. there are now two place to update if the original column names change). Additionally, you have to change type and rename in two separate steps.

#### Describe the solution you'd like

Could we support a dictionary syntax to both rename and specify the dtype of a column: `Dict[str, Tuple[str, str]]`? This would be particularly useful for data loading functions like `read_csv` but could also be useful independently for renaming and changing dtypes in one step.

```python
dtypes_and_names = {
    "originalColumnA": ("column_a", "int32"),
    "ORIGinal  Column B": ("column_b", "string"),
    "  Original COLUMN C": ("column_c", "category"),
}
# can work with dtype kwarg in data loading functions or perhaps a new kwarg?
df = pandas.read_csv("data.csv", dtype=dtypes_and_names)
# possibly also for the astype method?
df = df.astype(dtype=dtypes_and_names)
```

The above `dtypes_and_names` dictionary is easier to maintain and clearer to see the new names and datatypes. There could also be conventions for when a subset of columns only need to be renamed (or change datatype) such as `"column_d":(None, "int32")`. This is a bit similar to the named aggregation syntax that lets you aggregate and define the output name in one step.

#### API breaking implications

This should only be an enhancement and doesn't need to affect any current functionality / syntax. If it uses the `dtype` kwarg we could check the type of the value in the dictionary to see what syntax is being used and handle appropriately. Alternatively, this could use a new kwarg.

#### Describe alternatives you've considered

Currently, to do this I define the dictionary as per my above solution and then use dictionary comprehension to split it into two different dictionaries (renames and dtypes). I then use the currently supported syntax/functionality:

```python
dtypes_and_names = {
    "originalColumnA": ("column_a", "int32"),
    "ORIGinal  Column B": ("column_b", "string"),
    "  Original COLUMN C": ("column_c", "category"),
}
renames = {key: value[0] for key,value in dtypes_and_names.items()}
dtypes = {key: value[1] for key,value in dtypes_and_names.items()}
df = pandas.read_csv("data.csv", dtype=dtypes)
df = df.rename(columns=renames)
```

#### Additional context

Does anyone else think this would be useful or is there a better way to do it already that I am not aware of? If this could be useful I would be happy to work on a PR.

