使用大量匹配更快地替换列表

时间:2011-04-10 00:37:13

标签: python list

列表中的一个小问题并替换了一些列表条目。

可能有关于我的问题的一些信息。我的想法非常简单易行。我使用模块mmap来读出更大的文件。这是一些有7列和100万行的FORTRAN文件。有些值不符合FORTRAN输出的格式,我只有十颗星。我无法更改源代码中输出的格式,我必须处理这个问题。使用mmap加载文件后,我使用str.split()将数据转换为列表,然后搜索错误的值。请查看以下源代码:

f = open(fname,'r+b')
A = str(mmap.mmap(f.fileno(),0)[:]).split()
for i in range(A.count('********')):
    A[A.index('********')] = '0.0'

我知道这可能不是最好的解决方案,但它快速而且肮脏。好。如果A.count('********')很小,那就快了。其实这是我的问题。对于某些文件,替换方法不能很快地工作。如果它很大,需要花费很多时间。是否还有其他方法或其他方法来替换我的不良价值并且不浪费大量时间?

感谢您提供任何帮助或任何建议。

修改

方法list.count()如何运作?我也可以浏览整个列表并用我自己的替换它。

for k in range(len(A)):
    if A[k] == '**********': A[k] = '0.0'

对于许多替换来说,这会更快。但如果我只有一场比赛会更快吗?

5 个答案:

答案 0 :(得分:2)

如果您最终要将其转换为数组,您可以考虑使用numpy和能够处理缺失数据的np.genfromtxt

http://docs.scipy.org/doc/numpy/reference/generated/numpy.genfromtxt.html

使用二进制文件,您可以使用np.memmap,然后使用屏蔽数组来处理缺少的元素。

答案 1 :(得分:2)

代码中的主要问题是在循环中使用“A.index” - 。 index方法将在列表中线性行进,从“ * *”的开始到下一个出现 - 这会将O(n)问题转换为O(n²) - 因此你认为缺乏表现。

使用Python时,最明显的方法通常是最好的方法:因此,在这种情况下,在Python for循环中遍历列表将比C中的O(n²)循环更好。 cound和index方法。不那么明显的部分是内置函数“enumerate”的推荐用法,以从for循环的列表中获取项目值及其索引。

f = open(fname,'r+b')
A = str(mmap.mmap(f.fileno(),0)[:]).split()
for i, value in enumerate(A):
    if value == "********":
       A[i] = "0.0"

答案 2 :(得分:0)

如果在将A转换为一个巨大的字符串表示后,您首先可以通过调用A.replace('********', '0.0')方法更改所有错误值,然后将其拆分,您将获得相同的结果,可能要快得多。类似的东西:

f = open(fname,'r+b')
A = str(mmap.mmap(f.fileno(),0)[:]).replace('********', '0.0').split()

它会占用大量内存,但这通常是速度的折衷。

答案 3 :(得分:0)

fin = open(fname, 'r')
fout = open(fname + '_fixed', 'w')
for line in fin:
    # replace 10 asterisks by 7 spaces + '0.0'
    # If you don't mind losing the fixed-column-width format, 
    # omit the seven spaces
    line = line.replace('**********', '       0.0')
    fout.write(line)
fin.close()
fout.close()

或者,如果您的文件很小,请用此替换循环:

fout.write(fin.read().replace('**********', '       0.0'))

答案 4 :(得分:0)

不要操纵A,而是尝试使用列表推导来制作新的A:

A = [v if v != '********' else 0.0 for v in A]

我想你会发现这个惊人的快。