【问题标题】:set of keys for nested dictionaries嵌套字典的键集
【发布时间】:2018-01-12 21:46:45
【问题描述】:

我有几行来填充set

x = {1: {2: 4, 3: 6}, 5: {2:6, 10: 25, 14: 12}}

keys = set()
for y in x:
    for z in x[y]:
        keys.add(z)

# keys is now `set([2, 3, 10, 14])`

我无法摆脱我可以做得更好的感觉,但我想出的一切似乎都很棒。大多数实现首先构建一个list,这很烦人。在y 中有很多x,大多数y 有相同的z

# Builds a huuuuge list for large dicts.
# Adapted from https://stackoverflow.com/a/953097/241211
keys = set(itertools.chain(*x.values()))

# Still builds that big list, and hard to read as well.
# I wrote this one on my own, but it's pretty terrible.
keys = set(sum([x[y].keys() for y in x], []))

# Is this what I want?
# Finally got the terms in order from https://stackoverflow.com/a/952952/241211
keys = {z for y in x for z in x[y]}

原始代码是“最 Pythonic”还是单行代码更好?还有什么?

【问题讨论】:

  • for z in x 只是迭代字典的键。这些键本身不应再是可迭代的。你确定你发布了正确的代码吗?
  • 我会说方法 1(循环)、2(从链中设置 not 构建列表)和 4(嵌套集理解)都是有效的,Pythonic并且算法合理。 3(列表的总和)具有二次时间复杂度,应该被丢弃。您选择 3 个中的哪一个取决于您的喜好,以及您喜欢它的可读性、简洁性还是 C 优化。
  • @JacobIRR 谢谢。我是如此专注于替代品,以至于我没有测试原版。

标签: python python-2.7 set-comprehension


【解决方案1】:

我会用

{k for d in x.itervalues() for k in d}

itervalues()(在 Python 3 中只是 values())不构建列表,并且此解决方案不涉及字典查找(与 {z for y in x for z in x[y]} 相比)。

【讨论】:

    【解决方案2】:

    我会使用itertools 模块,特别是chain 类。

    >>> x = {1: {2: 4, 3: 6}, 5: {2:6, 10: 25, 14: 12}}
    >>> from itertools import chain
    >>> set(chain.from_iterable(x.itervalues()))
    set([2, 3, 10, 14])
    

    【讨论】:

      【解决方案3】:

      你可以使用dict.items():

      x = {1: {2: 4, 3: 6}, 5: {2:6, 10: 25, 14: 12}}
      final_x = set(i for b in [b.keys() for i, b in x.items()] for i in b)
      

      输出:

      set([2, 3, 10, 14])
      

      【讨论】:

      • dict.items() 在 Python 2 中创建字典项列表,这是 OP 想要避免的。然后[b.keys() for i, b in x.items()] 创建另一个列表。在该列表理解中,您调用 dict.keys(),它会创建另一个列表。
      猜你喜欢
      • 2014-03-30
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 2018-10-29
      • 2021-04-14
      相关资源
      最近更新 更多