Kvothe
Kvothe

Reputation: 285

Round list, list of lists, numpy array or other structure maintaining its structure

Is there some function to round something that could be a list, a list of lists, or a numpy array and output a rounded version of the same object. np.round (see for example https://stackoverflow.com/a/46994452/7238575) comes close but changes an object into a numpy array if it was a list. I would like to have a general rounding function that preserves the type of the data.

Upvotes: 0

Views: 116

Answers (1)

matszwecja
matszwecja

Reputation: 8005

You can start of from some implementation of deepcopy and modify what it does when it reaches singular values.

Deepcopy implementation based on: Implementing a copy.deepcopy() clone function

def deepRound(data, ndigits):
    if isinstance(data, dict):
        result = {}
        for key, value in data.items():
            result[key] = deepRound(value, ndigits)

        assert id(result) != id(data)

    elif isinstance(data, list):
        result = []
        for item in data:
            result.append(deepRound(item, ndigits))

        assert id(result) != id(data)

    elif isinstance(data, tuple):
        aux = []
        for item in data:
            aux.append(deepRound(item, ndigits))
        result = tuple(aux)

        assert id(result) != id(data)

    elif isinstance(data, set):
        aux = []
        for item in data:
            aux.append(deepRound(item, ndigits))
        result = set(aux)

        assert id(result) != id(data)

    elif isinstance(data, (int, float)):
        result = round(data, ndigits)
    else:
        raise ValueError("Unsupported data type: {}".format(type(data)))

    return result

As written, it handles lists, dicts, sets and tuples for collections and ints and floats for rounding. Should you need to have other types handled you'd have to either add them to the above implementation or implement some common interface for that function.

Upvotes: 1

Related Questions