gpt4 book ai didi

python - 根据值对列表中的项目进行配对

转载 作者:太空宇宙 更新时间:2023-11-03 17:09:11 25 4
gpt4 key购买 nike

我有一个如下所示的 xml 文件:

<edge from="0/0" to="0/1" speed="10"/>
<edge from="0/0" to="1/0" speed="10"/>
<edge from="0/1" to="0/0" speed="10"/>
<edge from="0/1" to="0/2" speed="10"/>
...

请注意,存在成对的“从”到“到”,反之亦然。 (在上面的示例中,只有 ("0/0","0/1")("0/1","0/0") 对可见,但每个条目都有一个伙伴。)另请注意,这些对没有排序。

该文件描述 SUMO 内的边缘网络模拟。我想为不同的街道随机分配新的速度。然而,每<edge>条目仅描述街道的一个方向(车道)。因此,我需要找到它的“伙伴”。

以下代码仅按车道分配速度值:

import xml.dom.minidom as dom
import random
edgexml = dom.parse("plain.edg.xml")
MAX_SPEED_OPTIONS = ["8","9","10"]
for edge in edgexml.getElementsByTagName("edge"):
x = random.randint(0,2)
edge.setAttribute("speed", MAX_SPEED_OPTIONS[x])

是否有一种简单的(Pythonic)方法可以将这些对收集到元组中,然后为两者分配相同的值?

如果您知道使用 SUMO 工具解决我的问题的更好方法,我也会很高兴。不过,我仍然对如何解决 python 中给定的抽象列表问题感兴趣,因为它不仅仅是相关问题中的简单 zip。

最佳答案

好吧,您可以遍历边列表并在所有边上嵌套另一个迭代来搜索可能的伙伴。由于这是二次复杂度,我们甚至可以通过仅遍历嵌套运行中尚未访问的边来减少计算时间。

解决方案

(有关详细说明,请向下滚动)

import xml.dom.minidom as dom
import random

edgexml = dom.parse('sampledata/tmp.xml')
MSO = [8, 9, 10]

edge_groups = []
passed = []
for idx, edge in enumerate(edgexml.getElementsByTagName('edge')):
if edge in passed:
continue

partners = []
for partner in edgexml.getElementsByTagName('edge')[idx:]:
if partner.getAttribute('from') == edge.getAttribute('to') \
and partner.getAttribute('to') == edge.getAttribute('from'):
partners.append(partner)

edge_groups.append([edge] + partners)
passed.extend([edge] + partners)

for e in edge_groups:
print('NEW EDGE GROUP')
x = random.choice(MSO)
for p in e:
p.setAttribute('speed', x)
print(' E from "%s" to "%s" at "%s"' % (p.getAttribute('from'), p.getAttribute('to'), x))

产生输出:

NEW EDGE GROUP
E from "0/0" to "0/1" at "8"
E from "0/1" to "0/0" at "8"
NEW EDGE GROUP
E from "0/0" to "1/0" at "10"
NEW EDGE GROUP
E from "0/1" to "0/2" at "9"

详细说明

edge_groups = []
passed = []

初始化结果结构edge_groups,它将是一个列表列表,其中包含分组中的合作边。 passed 的附加列表将帮助我们避免结果中出现冗余边缘。

for idx, edge in enumerate(edgexml.getElementsByTagName('edge')):

开始迭代所有边的列表。我在这里使用 enumerate 来同时获取索引,因为我们的嵌套迭代只会迭代从当前索引开始的子列表,以降低复杂性。

    if edge in passed:
continue

如果我们之前在任何时间点访问过该边缘,请停止。仅当该边之前已被识别为另一个列表的伙伴时(由于基于索引的子列表),才会发生这种情况。如果它已经被作为另一个列表的伙伴,我们毫无疑问可以忽略它。

    partners = []
for partner in edgexml.getElementsByTagName('edge')[idx:]:
if partner.getAttribute('from') == edge.getAttribute('to') \
and partner.getAttribute('to') == edge.getAttribute('from'):
partners.append(partner)

初始化助手列表以存储识别的合作伙伴边缘。然后,从当前索引开始遍历剩余列表中的所有边。 IE。不要迭代已经在外部迭代中传递的边。如果潜在合作伙伴是实际合作伙伴(来自/结束匹配),则将其附加到我们的合作伙伴列表中。

    edge_groups.append([edge] + partners)
passed.extend([edge] + partners)

嵌套迭代已通过,partners 保存当前边缘 的所有已识别合作伙伴。将它们插入一个列表并将其附加到结果变量edge_groups。由于检查 2 级列表 Edge_groups 来查看我们是否已经在下一次运行中遍历了一条边是不必要的复杂操作,因此我们将另外保留一个已使用节点的列表并将其称为 通过

for e in edge_groups:
print('NEW EDGE GROUP')
x = random.choice(MSO)
for p in e:
p.setAttribute('speed', x)
print(' E from "%s" to "%s" at "%s"' % (p.getAttribute('from'), p.getAttribute('to'), x))

最后,我们遍历结果 edge_groups 中的所有边缘组,从 MSO 中随机绘制速度(提示:使用 random.choice() 从列表中随机选择),并将其分配给该组中的所有边。

关于python - 根据值对列表中的项目进行配对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34289364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com