使用python中的列表推导修改列表的一部分

时间:2014-01-14 19:35:10

标签: python list

我有一个类似于

的列表
test = ['A','B','C','D D','E E','F F']

我想测试成为以下内容(即删除的空格)

test = ['A', 'B', 'C', 'DD', 'EE', 'FF']

我在Python中使用了列表推导来实现这个目标:

>>> [re.sub(' ','',i) for i in test]
['A', 'B', 'C', 'DD', 'EE', 'FF']

我的问题是 - 如果我明确地不希望re.sub(' ','',i)在我列表的前三个元素上运行怎么办?我只希望re.sub函数在'DD','EE'和'FF'上运行。

这种方式有效吗?我理解列表理解会占用内存,因为Python会复制它。

test2[3:] = [re.sub(' ','',i) for i in test[3:]]

或者我应该像这样循环遍历我想要修改的测试值:

for i in range(3,len(test)):
    print i
    test[i] = re.sub(' ','',test[i])

3 个答案:

答案 0 :(得分:3)

首先,听起来你过早地进行了优化。

其次,您可以通过单一列表理解来表达您的要求:

In [5]: test = ['A','B','C','D D','E E','F F']

In [6]: [t if i < 3 else re.sub(' ', '', t) for (i, t) in enumerate(test)]
Out[6]: ['A', 'B', 'C', 'DD', 'EE', 'FF']

最后,我的建议是首先关注正确性,然后关注可读性。一旦实现了这些目标,请对代码进行分析,以查看瓶颈所在,然后再针对性能进行优化。

答案 1 :(得分:2)

re.substr.replacestr.translate中最好的是str.replace。因此,请使用 str.replace

这是一个小时间比较。

import re

def test1():
    test = ['A','B','C','D D','E E','F F']
    test[3:] = [re.sub(' ','',i) for i in test[3:]]

def test2():
    test = ['A','B','C','D D','E E','F F']
    test[3:] = [i.replace(" ", "") for i in test[3:]]

def test3():
    test = ['A','B','C','D D','E E','F F']
    test[3:] = [item.translate(None, " ") for item in test[3:]]

from timeit import timeit
print timeit("test1()", "from __main__ import test1")
print timeit("test2()", "from __main__ import test2")
print timeit("test3()", "from __main__ import test3")

我机器上的输出

3.96201109886
0.985305070877
1.11600804329

注意:正如@roippi在评论中提到的,str.translate在Python 3.x中不会以此形式运行。所以,如果你使用Python 3.x

,请在比赛中忽略它

答案 2 :(得分:1)

  

我的问题是 - 如果我明确地不想要re.sub('','',i)怎么办?   运行我列表的前三个元素?

好的,首先回答这个问题:

您可以使用enumerate和条件表达式来指定您想要的行为&lt; 3和i> = 3:

[x if i<3 else re.sub(' ','',x) for i,x in enumerate(test)]
['A', 'B', 'C', 'DD', 'EE', 'FF']

请注意sub可以更直接地处理这个简单的str.replace操作。

(我将不讨论这种优化是否值得,除了说前三个元素没有做re.sub所节省的时间是微不足道的)