A uniqueness check in which False!= 0

You need to check JSON for uniqueness. The validation conditions assume that the collection [false, 0] is unique, that is, the logical type is not equal to a number.

How do I make such a check on Python if its boolean type is a subclass of int and is equal to numbers 1/0?

Examples of unique collections:

[1, True]
[[1], [True]]
[[[1], "foo"], [[True], "foo"]]
[{"foo": {"bar": [1]}}, {"foo": {"bar": [True]}})]

Direct comparison returns True:

{"foo": {"bar": [1]}} == {"foo": {"bar": [True]}})  # True

I will clarify that I am mainly interested in the unfolding algorithm, which can be applied to the latest designs. The function for comparing 1 with True is.

I think that the problem can be reduced to BFS, but everything is complicated by the fact that JSON simultaneously contains both dictionaries and lists. I would like to find a universal and, preferably, non-recursive traversal algorithm.

Author: nomnoms12, 2020-05-21

2 answers

a = 0
b = False
print(a == b) # True
print(a == b and type(a) == type(b)) # False

You can compare values and types at the same time

def isUnique(a) -> bool:
    items = set([])

    for item in a:
        items.add(str([item]))

    return items.__len__() == a.__len__()

print(isUnique([1, True])) #True
print(isUnique([[1], [True]])) #True
print(isUnique([[[1], "foo"], [[True], "foo"]])) #True
print(isUnique([1,1])) # False
print(isUnique([[[True], "foo"], [["True"], "foo"]])) # True
print(isUnique([[[True], "foo"], [[True], "foo"]])) #False
 0
Author: pagislav, 2020-05-21 23:59:15

Implemented it as follows:

def unbool(element, true=object(), false=object()):
    """
    A hack to make True and 1 and False and 0 unique for ``uniq``.
    """

    if element is True:
        return true
    elif element is False:
        return false
    return element


def unbool_nested(element):
    """
    Iterative implementation of breadth-first search for nested unbooling
    """

    if not isinstance(element, (list, dict)):
        return unbool(element)

    result = [] if isinstance(element, list) else {}
    stack = [(element, result)]
    while stack:
        element, new = stack.pop()
        items = enumerate(element) if isinstance(element, list) else element.items()
        for key, item in items:
            if not isinstance(item, (list, dict)):
                x = unbool(item)
            else:
                sub = [] if isinstance(item, list) else {}
                x = sub
                stack.append((item, sub))

            if isinstance(new, list):
                new.append(x)
            else:
                new[key] = x
    return result


def uniq(container):
    """
    Check if all of a container's elements are unique.

    Successively tries first to rely that the elements are hashable. If not, it goes to brute force.
    """

    try:
        return len(set(unbool(i) for i in container)) == len(container)
    except TypeError:
        seen = []
        for element in container:
            element = unbool_nested(element)
            if element in seen:
                return False
            seen.append(element)
    return True
 0
Author: nomnoms12, 2020-05-22 22:34:13