【问题标题】:how to ignore the order of elements in a tuple如何忽略元组中元素的顺序
【发布时间】:2016-08-13 20:02:29
【问题描述】:

我使用元组作为我创建的字典的键。例如:

example_dict = {}
example_dict[("A", "B")] = "1"

稍后当我希望修改字典中条目的值时,我目前无法控制元组的顺序。例如:

("B", "A") may be the case, instead of ("A", "B")

通过我在 python shell 中尝试的简单 == 比较,我知道这些元组并不相等。

我想知道如何解决这个问题?我怎样才能使以下内容不产生 KeyError:

print (example_dict["B", "A"])

有没有办法对元组的元素进行一致的排序?有没有办法完全忽略订单?还有其他解决方法吗?我知道我可以将元组的所有排列作为键包含在字典中,然后稍后整理不同排列的值。我强烈希望避免这样做,因为这只会增加问题的难度和复杂性。

【问题讨论】:

    标签: python dictionary tuples


    【解决方案1】:

    通常的方法是对键进行排序:

    example_dict[tuple(sorted(key_tuple))] = "1"
    

    使用 freezesets 作为键(如果元组中没有重复元素):

    example_dict[frozenset(key_tuple)] = "1"
    

    或使用 (item, count) 元组的 freezesets 作为键(如果元组中可能存在重复元素):

    example_dict[frozenset(Counter(key_tuple).viewitems())] = "1"
    

    无论您选择哪个选项,都必须在查找值时应用相同的转换。

    【讨论】:

      【解决方案2】:

      不要使用tuple,而是使用frozensetfrozenset 只是一个常数 set,就像 tuple 可以被认为是一个常数 list

      这是一个示例(来自 Python 3,但它也适用于 Python 2):

      >>> d = {}
      >>> k1 = frozenset((1, 2))
      >>> k2 = frozenset((2, 1))
      >>> k1
      frozenset({1, 2})
      >>> k2
      frozenset({1, 2})
      >>> k1 == k2
      True
      >>> d[k1] = 123
      >>> d[k2]
      123
      >>> 
      

      【讨论】:

        【解决方案3】:

        您希望您的字典键是“集合”(集合是一个集合,其中一个项目在集合中或不在集合中,但没有顺序概念)。幸运的是,python 有你需要的东西。特别是因为你需要一些可散列的东西,你想使用frozenset

        >>> example_dict = {}
        >>> example_dict[frozenset(("A", "B"))] = "1"
        >>> example_dict[frozenset(("B", "A"))]
        '1'
        >>> example_dict[frozenset(("A", "B"))]
        '1'
        

        【讨论】:

        • 集合也没有元素多重性的概念。当您的元组的长度都为 2 时,这并不重要,但是当您有三个元素并且您无法区分 ("A", "A", "B")("A", "B", "B") 时,或者您的元组可以有不同的长度而您不能区分时,它可能会变得混乱区分("A",)("A", "A")。如果您尝试执行 for a, b in example_dict 之类的操作,它也会中断。
        • 对此的效率有何评论?就内存存储大小而言,frozensets 似乎比tuples 大得多。
        • @sudo 它们更大,但是随着使用的字符串的大小增加,元组也会增加,但是冻结集似乎保持大小。 codepile.net/pile/zRge1X0l
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-07-31
        • 2020-06-21
        • 2023-03-21
        • 2018-08-16
        • 2011-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多