【问题标题】:Python - Better way to iterate complex list than nested for loopsPython - 迭代复杂列表比嵌套 for 循环更好的方法
【发布时间】:2018-08-08 05:35:46
【问题描述】:

我正在用这种格式在 python 中迭代一个复杂的列表:

[
  {
    <parent id>: [
      <child id>,
      <child id>
    ],
    <parent id>: [
      <child id>
    ]
  },
  {
    <parent id>: [
      <child id>,
      <child id>,
      <child id>
    ],
    <parent id>: [
      <child id>
    ]
  }
]

列表将包含 dict 作为元素。这些字典有&lt;parent id&gt; 的键和&lt;child id&gt; 列表的值

不同的dict中可以有相同的&lt;parent id&gt;,但&lt;child id&gt;只能属于一个&lt;parent id&gt;。一个例子是这样的:

[
  {
    2: [1, 5],
    3: [3, 7],
    4: [6]
  },
  {
    1: [2, 4, 8],
    4: [6]
  }
]

父 id 4 在两个 dict 元素中,但所有子 id 对于父 id 都是唯一的。

现在我将这个数据结构作为输入进行迭代,因为我想确保满足所有孩子对父 ID 唯一的条件。这是我的代码:

def check_format(self, mapping):
    # mapping is the data structure
    unique_parent_list = []
    child_list = []

    for x in range(0, 2):
        for parent in mapping[x].keys():
            if parent not in unique_parent_list:
                unique_parent_list.append(parent)
                for child in mapping[x][parent]:
                    child_list.append(child)
    if len(child_list) > len(set(child_list)):
        return 'Condition not met'
    else:
        return 'Condition met'

这可行,但我不喜欢它是 O^4 复杂性或类似的东西。有没有办法简化或编码以获得更好的性能?

【问题讨论】:

  • 请为您的变量添加更多描述性名称。 key -> parenty -> child 例如。

标签: python for-loop nested-loops


【解决方案1】:

你显然有从孩子到父母的映射关系。我能想到的最简单的事情就是用孩子作为键来制作字典。如果遇到已经在里面的child,检查parent值。

查找和插入在恒定时间内发生(字典键实际上是一个哈希集)。您还可以更有效地使用短路,因为您可以在发现有多个父母的孩子的那一刻停止:

def check_format(map_list):
    check = {}
    for parent, children in (i  for d in map_list for i in d.items()):
        for child in children:
            if check.setdefault(child, parent) != parent:
                return False
    return True

这将对每个子节点仅迭代一次,并使用dict.setdefault 对每个子节点执行恒定时间(理想情况下)操作。

【讨论】:

  • 非常感谢。你是摇滚明星
【解决方案2】:

你确定这是 O(3) 复杂度吗?至于什么?

这段代码对你来说太慢了吗?如果您想查看所有孩子,除了像这样遍历它们之外真的没有别的了。

但是。考虑将unique_parent_listchild_list 设置为集合而不是列表。这可能会使in 检查更快(O(log(n) 与 O(1) 相比)。但如果你关心你应该分析一下,看看情况是否如此。

如果您在child_list 中检查条件,您也可以在发现重复的孩子后立即退出(如果格式错误)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多