Skip to main content
 首页 » 编程设计

python之Python 中的字符串操作

2025年05月04日19bjzhanghao

我正在将一些代码从另一种语言转换为 Python。该代码将一个相当大的文件读入一个字符串,然后通过数组索引对其进行操作,例如:

str[i] = 'e' 

由于字符串是不可变的,这不能直接在 python 中工作。在 python 中执行此操作的首选方法是什么?

我见过 string.replace() 函数,但它返回字符串的副本,这听起来不是很理想,因为在这种情况下字符串是整个文件。

请您参考如下方法:

假设您没有使用 UTF-8 等可变长度文本编码,您可以使用 array.array:

>>> import array 
>>> a = array.array('c', 'foo') 
>>> a[1] = 'e' 
>>> a 
array('c', 'feo') 
>>> a.tostring() 
'feo' 

但是由于您正在处理文件的内容,mmap应该更有效率:

>>> f = open('foo', 'r+') 
>>> import mmap 
>>> m = mmap.mmap(f.fileno(), 0) 
>>> m[:] 
'foo\n' 
>>> m[1] = 'e' 
>>> m[:] 
'feo\n' 
>>> exit() 
% cat foo 
feo 

这是一个快速基准测试脚本(对于非 Unix 操作系统,您需要将 dd 替换为其他内容):

import os, time, array, mmap 
 
def modify(s): 
    for i in xrange(len(s)): 
        s[i] = 'q' 
 
def measure(func): 
    start = time.time() 
    func(open('foo', 'r+')) 
    print func.func_name, time.time() - start 
 
def do_split(f): 
    l = list(f.read()) 
    modify(l) 
    return ''.join(l) 
 
def do_array(f): 
    a = array.array('c', f.read()) 
    modify(a) 
    return a.tostring() 
 
def do_mmap(f): 
    m = mmap.mmap(f.fileno(), 0) 
    modify(m) 
 
os.system('dd if=/dev/random of=foo bs=1m count=5') 
 
measure(do_mmap) 
measure(do_array) 
measure(do_split) 

我在用了几年的笔记本电脑上得到的输出符合我的直觉:

5+0 records in 
5+0 records out 
5242880 bytes transferred in 0.710966 secs (7374304 bytes/sec) 
do_mmap 1.00865888596 
do_array 1.09792494774 
do_split 1.20163106918 

因此 mmap 稍快一些,但建议的解决方案都没有特别不同。如果您发现差异很大,请尝试使用 cProfile看看有什么花时间。