我有一个类似于
的列表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])
答案 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.sub
,str.replace
和str.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
所节省的时间是微不足道的)