将列表中的元素替换为另一个列表中的元素 - Python

时间:2014-10-30 00:28:26

标签: python list

我有一个名为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']

替换rule.start的所有元素

最后,我想将所有元素评估为命令,如下所示:fd(var, scale)

并且:rt(var, 60) # 60 is from the list.

2 个答案:

答案 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进行更新;相反,它会针对匹配的每个elemelem进行更新,这可能是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来实现它安全使用