在循环中进行多次替换时变异列表

时间:2014-08-07 20:21:43

标签: python list loops mutable

我有一个csv文件,其中一列在test.csv文件中有以下数据

3 0JKT02 CX85d
3 0JNAd0 CP80d
3 0KAAd0 CT894
3 0KAAd0 CT895
3 0LARd0 CL003
3 0JNA10 CL80d
3 0JNA20 CL80d
3 0JNA30 CL80d
3 0JNA40 CL80d
3 0FAK3e CL00v
3 0FAK3e CT00e

我想要做的是用实例替换所有小帽(d,e和v)。在这里

d = [1,2,3,4]
e = [1,2]
v = [3,4]

所以以最后两个例子为例,我需要得到 3 0FAK31 CL0033 0FAK32 CT0033 0FAK31 CL0043 0FAK32 CT004

我已经声明了一个包含所有旧值的数组,我遍历这个数组并逐个更新它,因为它变异了,我没有得到我预期的结果。它似乎在删除'之后跳过了。代码,只是搞砸了列表。此外,它仍然具有e和v变量的' oldarray'。我很沮丧,请帮忙。此外,如果你可以批评我的代码,并建议更多的pythonic方式,我会很感激。这是代码......

class Compare:
    def __init__(self):
        f1 = open('test.csv','r')
        self.oldarray = []
        for row1 in f1:
            self.oldarray.append(row1.strip('\n').strip())  
        self.dict1 = {'d':[1,2,3,4],'e':['1','2'], 'v':['3','4']}

    def work(self,key,values):
        for item in self.oldarray:
            if key in item:
                for each in values:
                    self.oldarray.append(item.replace(key,each))
                self.oldarray.remove(item)        

    def do(self):
        for key,values in self.dict1.items():
            self.work(key,values)

if __name__ == '__main__':
    import csv
    x = Compare()
    x.do()
    for i in x.oldarray:
        print i

1 个答案:

答案 0 :(得分:0)

考虑使用生成器而不是在迭代它时改变列表,pythonic方法是编写一个接收一个序列并产生另一个序列的函数。您可以接受一系列行,然后根据您的替换为每个输入行生成一行或更多行。这只需要一个函数,而不是一个类。

您的"额外"由于您一次只执行一个replace(),因此保留了变量。听起来您想置换可用字母组合进行替换,因此如果同时存在ev,则最终会输出4行。这是一个独立的示例,说明如何使用itertools.product来解决这个问题,因为我不认为你会像循环一样轻松地到达那里。

import itertools
mapping = {'d':[1,2,3,4],'e':['1','2'], 'v':['3','4']}
line = "3 0FAK3e CL00v"
subs = (
    [(key, value) for value in mapping[key]]
    for key in mapping
    if key in line
    )
for combination in itertools.product(*subs):
    lineb = line
    for letter, number in combination:
        lineb = lineb.replace(str(letter), str(number))
    print lineb

如果您关心结果订单,请不要使用字典或排序辅助数据结构。 Dicts有任意键的顺序。