python 如何在一个方法中递归地固定通过参数传递的数据类型?

huus2vyu  于 2023-08-02  发布在  Python
关注(0)|答案(2)|浏览(74)

我正在尝试解决一个需要递归地固定数据类型的练习,但我在递归情况下遇到了问题:
该函数返回一个不可变的等效数据结构(可以用于集合中的值或字典中的键)。类型int、str和frozenset已经是不可变的。将集合转换为冻结集合;以相同的顺序将元组中的所有值转换为它们的不可变等价物);将一个列表转换成一个元组(具有其值的不可变等价物,顺序相同);将dict转换为2元组的元组
我查到了基本情况,但没查到别的...

def immutify(a : 'an int, str, list, tuple, set, or dict') -> 'an int, str, tuple, or forzenset':
    if (isinstance(a, int)):
        return a
    if (isinstance(a, str)):
        return a
    if (isinstance(a, tuple)):
        # immutify each element in it?
    if (isinstance(a, frozenset)):
        # immutify each element in it?
    if (isinstance(a, set)):
        # return an immutified frozenset of a?
    if (isinstance(a, list)):
         # return an immutified tuple of a?
    if (isinstance(a, dict)):
        #return an immutified tuple of a?

字符串
预期输出为:

immutify(1) # -->1
immutify('a') # -->'a'
immutify( (1, 2, 3)) # -->(1, 2, 3)
immutify( frozenset([1, 2, 3])) # -->frozenset({1, 2, 3})
immutify( [1, 2, 3, 4, 5, 6]) # -->(1, 2, 3, 4, 5, 6)
immutify( [1, 2, [3, [4], 5], 6])# -->(1, 2, (3, (4,), 5), 6)
immutify( [1, 2, (3, [4], 5), 6]) # -->(1, 2, (3, (4,), 5), 6)
immutify( [{1,2}, {3,frozenset([4,5])}, {6,7}]) #-->(frozenset({1, 2}), frozenset({3, frozenset({4, 5})}), frozenset({6, 7}))
immutify( [{1,2}, {3,frozenset([4,5])}, [{5,6}]]) #-->(frozenset({1, 2}), frozenset({3, frozenset({4, 5})}), (frozenset({5, 6}),))
immutify( {'b' : [1,2], 'a' : {'ab': {1,2}, 'aa' : (1,2)}}) #-->(('a', (('aa', (1, 2)), ('ab', frozenset({1, 2})))), ('b', (1, 2)))


上一篇:I almost got there:

def immutify(a : 'an int, str, list, tuple, set, or dict') -> 'an int, str, tuple, or forzenset':
    if (isinstance(a, int)):
        return a
    if (isinstance(a, str)):
        return a
    if (isinstance(a, tuple)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return tuple(out)
    if (isinstance(a, frozenset)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return frozenset(out)
    if (isinstance(a, set)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return tuple(out)

    if (isinstance(a, list)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return tuple(out)
    if (isinstance(a, dict)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return tuple(out)

41zrol4v

41zrol4v1#

我知道了

def immutify(a : 'an int, str, list, tuple, set, or dict') -> 'an int, str, tuple, or forzenset':
    if (isinstance(a, int)):
        return a
    if (isinstance(a, str)):
        return a
    if (isinstance(a, tuple)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return tuple(out)
    if (isinstance(a, frozenset)):
        #out = []
        #for elem in a:
            #new = immutify(elem)
            #out.append(new)
        #return frozenset(out)
        return a
    if (isinstance(a, set)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return frozenset(out)

    if (isinstance(a, list)):
        out = []
        for elem in a:
            new = immutify(elem)
            out.append(new)
        return tuple(out)
    if (isinstance(a, dict)):
        tup = []
        pair = []
        for elem in a:
            new1 = immutify(elem)
            new2 = immutify(a[elem])
            pair.append(new1)
            pair.append(new2)
            tup.append(tuple(pair))
            pair = []
        return tuple(tup)

字符串

0pizxfdo

0pizxfdo2#

更新了较新版本的Python的答案。

from typing import Any, Sequence, Mapping

# Since typing.Hashable doesn't check recursively you actually
# have to try hashing it.
def is_hashable(obj):
    try:
        hash(obj)
        return True
    except:
        return False

def to_hashable(obj: Any):
    # So that we don't infinitely recurse since frozenset and tuples
    # are Sequences.
    if is_hashable(obj):
        return obj
    elif isinstance(obj, Mapping):
        return frozenset([(to_hashable(k), to_hashable(v)) for k, v in obj.items()])
    elif isinstance(obj, Sequence):
        return frozenset([to_hashable(i) for i in obj])
    else:
        raise ValueError("Object is not hashable")

to_hashable({1: 2, 3: [4, 5]})  # frozenset({(1, 2), (3, frozenset({4, 5}))})

字符串
有两件事值得注意,有一个Hashable类,但它并不像你最初假设的那样有用,这就是为什么你必须实际尝试对对象进行哈希运算。

isinstance(({}, {}), Hashable) # == True
hash(({}, {})) # raises ValueError


第二个是,在写这篇文章的时候,还没有一个类意味着“不是字符串的可迭代”,这是 * 到目前为止 * 最常见的情况。然而,由于字符串是可散列的,我们不必在这里担心它。如果你修改了这段代码,你需要注意一些事情。
链接到相关文档。typing中的值是collections.abc中的类的别名,但更常用。

  • collections.abc.Sequence
  • collections.abc.Mapping
  • collections.abc.Hashable

相关问题