我有一个名为rule.start.
的列表在此列表中,所有元素都等于另一个名为com.empty
的列表中的元素。我希望rule.start
中的元素被com.empty
中相同元素后面的元素替换。我该怎么做?
rule.start
看起来像这样:
['F', 'L', 'G', 'L', 'F', 'R', 'F', 'R', 'F', 'L', 'G', 'L', 'F', 'L', 'F', 'L', 'G', 'L', 'F', 'L',........]
com.empty
看起来像这样:
['F', ['fd'], 'G', ['fd'], 'L', ['lt', '60'], 'R', ['rt', '60']]
我试过这个:
wut = 0
for elem in rule.start:
v = 1
for mel in com.empty[::2]:
if elem == mel:
rule.start[wut] = com.empty[v]
print elem
print mel
wut +=1
v += 2
但它只是用['fd']
最后,我想将所有元素评估为命令,如下所示:fd(var, scale)
并且:rt(var, 60) # 60 is from the list.
答案 0 :(得分:3)
首先,如果您有一个字典,将键映射到值,而不是交替键和值的列表,这将更容易编写,并且效率更高。你可以做一个单行:
mapping = dict(zip(com.empty[::2], com.empty[1::2]))
但是如果你不理解它是如何工作的,你可以这样做,你应该能够理解(根据你的代码)。
mapping = {}
key = None
for mel in com.empty:
if key is None:
key = mel
else:
mapping[key] = mel
key = None
或者,更好的是,如果可能的话,首先更改代码以构建字典而不是交替值列表。
现在,一旦你拥有了这个,你的循环变得简单,很难出错:
for wut, elem in enumerate(rule.start):
rule.start[wut] = mapping.get(elem, elem)
我正在使用enumerate
,因此您不必手动跟踪wut
,而是使用dict.get
方法而不是循环所有的键和值,这是你迷失的棘手部分。
或者,更简单:
rule.start = [mapping.get(elem, elem) for elem in rule.start]
但是,如果你想知道你的尝试有什么问题:
您从v = 1
开始。对于每个mel
,您将v
增加2 if elem == mel
。否则,它将保持为1.因此,第一次elem == mel
,您将拥有v = 1
,因此您将com.empty[1]
分配给{{1} }}。如果您将rule.start[wut]
移到循环外,那将解决此问题。
你也有类似的问题v + 2
在错误的地方。它应该针对每个wut += 1
进行更新;相反,它会针对匹配的每个elem
和elem
进行更新,这可能是0次或(理论上)3次。
正确获取这些内容是错误的重要来源,这正是mel
存在的原因。
答案 1 :(得分:1)
我很想从将com.empty重写为dict开始,这就是你真正想要的。
c2 = {key:val for (key, val) in zip (com.empty[0::2], com.empty[1::2])}
然后它很简单:
rule.start.new = [c2[key] for key in rule.start]
当然,如果你在rule.start中有一个不在com.empty中的密钥,那么这会失败 - 我会让你点缀我并且越过t' s来实现它安全使用