【问题标题】:Dictionary whose key is independent on the order of elements it contains其键与其包含的元素顺序无关的字典
【发布时间】:2014-02-07 18:13:16
【问题描述】:

我想在 Python 中创建一个字典,它的键将独立于它包含的元素的顺序。这是一个例子:

items = {1: 2, 2: 3, 4: 5}
comb = {(key1, key2): 0 for key2 in items.keys() for key1 in items.keys() if key1 != key2}

输出:

{(1, 2): 0, (1, 4): 0, (2, 1): 0, (4, 2): 0, (4, 1): 0, (2, 4): 0}

但我只想拥有:

{(1, 2): 0, (1, 4): 0, (2, 4): 0}

所以键 (1, 2) 应该等于 (2, 1)。对于长度超过 2 的元组(例如 (2, 3, 4) = (4, 3, 2)),这也需要是正确的。

【问题讨论】:

  • @Bakuriu:OP 正在遍历密钥,而不是测试收容措施。最好还是放弃keys 调用,但是使用keys 不会导致在使用keys 测试遏制时会发生的性能大幅下降。
  • @user2357112 你说得对,我错过了第二个for... 但是,正如你所说,它仍然没用。同样在 python3 中它可能只会增加一点开销,但在 python2 中它会在循环之前创建一个键列表,几乎是 dict-comprehension 所花费的时间的两倍。
  • @Bakuriu:你说得对,它没用而且很浪费——而且更重要的是,它使代码更冗长、更难阅读……但你首先优化了错误的部分。尝试用笛卡尔积构建combinations 的浪费成本(特别是考虑到在对答案的评论中,他表示想要为 3 个或更多做这个)将淹没不必要地构建一些小列表的成本……

标签: python dictionary key tuples


【解决方案1】:

使用itertools.combinations

>>> {keys: 0 for keys in itertools.combinations(items, 2)}
{(1, 2): 0, (2, 4): 0, (1, 4): 0}

with dict.fromkeys(仅在值不可变时使用dict.fromkeys;该值由所有条目共享):

>>> dict.fromkeys(itertools.combinations(items, 2), 0)
{(1, 2): 0, (2, 4): 0, (1, 4): 0}

>>> dict.fromkeys(itertools.combinations(items, 3), 0)
{(1, 2, 4): 0}

【讨论】:

    【解决方案2】:

    如果您希望在一般情况下拥有与顺序无关的键,您可以使用frozensets 作为键而不是元组:

    >>> {frozenset((key1, key2)): 0 for key2 in items.keys() for key1 in items.keys() if key1 != key2}
    {frozenset({2, 4}): 0, frozenset({1, 2}): 0, frozenset({1, 4}): 0}
    

    对于OP的具体情况,前面提到的解决方案会更好。但是,如果需要真正与顺序无关的键,我提出的解决方案可能是一种比对索引排序更优雅(更快)的方法。

    【讨论】:

      猜你喜欢
      • 2018-08-02
      • 2022-12-24
      • 2023-03-05
      • 2022-01-25
      • 1970-01-01
      • 2016-02-27
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多