from typing import Any
from typing import List


def default_uncollate(batch: Any) -> List[Any]:
    """This function is used to uncollate a batch into samples. The following conditions are used.

    >>> import torch
    >>> from pprint import pprint
    >>> batch = {"input": torch.zeros([5, 3, 224, 224]), "target": torch.zeros([5, 3, 224, 224]),
    ...          "metadata": {
    ...             'size': [torch.tensor([266, 266, 266, 266, 266]), torch.tensor([266, 266, 266, 266, 266])],
    ...             'height': torch.tensor([266, 266, 266, 266, 266]),
    ...             'width': torch.tensor([266, 266, 266, 266, 266])
    ... }}
    >>> bbatch = default_uncollate(batch)
    >>> len(bbatch)
    5
    >>> print(bbatch[0].keys())
    dict_keys(['input', 'target', 'metadata'])
    >>> print(bbatch[0]["input"].size(), bbatch[0]["target"].size())
    torch.Size([3, 224, 224]) torch.Size([3, 224, 224])
    >>> pprint(bbatch[0]["metadata"])
    {'height': tensor(266),
     'size': (tensor(266), tensor(266)),
     'width': tensor(266)}
    """
    if isinstance(batch, dict):
        elements = [default_uncollate(element) for element in batch.values()]
        return [dict(zip(batch.keys(), element)) for element in zip(*elements)]
    if isinstance(batch, (list, tuple)):
        return list(zip(*batch))
    return list(batch)