在 Python 代码中运行"wc -l <filename>"



我想对巨大的文件(每个文件要运行数十万行(进行10倍的交叉验证。我想在每次开始读取文件时做一个"wc-l",然后生成固定次数的随机数,每次都将该行号写入一个单独的文件中。我使用的是:

import os 
for i in files:
    os.system("wc -l <insert filename>").

如何在那里插入文件名。这是一个变量。我浏览了文档,但它们大多列出了ls命令,没有这个问题。

让我们比较一下:

from subprocess import check_output
def wc(filename):
    return int(check_output(["wc", "-l", filename]).split()[0])
def native(filename):
    c = 0
    with open(filename) as file:
        while True:
            chunk = file.read(10 ** 7)
            if chunk == "":
                return c
            c += chunk.count("n")
def iterate(filename):
    with open(filename) as file:
        for i, line in enumerate(file):
            pass
        return i + 1

快去计时功能!

from timeit import timeit
from sys import argv
filename = argv[1]
def testwc():
    wc(filename)
def testnative():
    native(filename)
def testiterate():
    iterate(filename)
print "wc", timeit(testwc, number=10)
print "native", timeit(testnative, number=10)
print "iterate", timeit(testiterate, number=10)

结果:

wc 1.25185894966
native 2.47028398514
iterate 2.40715694427

因此,wc在150 MB压缩文件上的速度大约是我测试的速度的两倍,其中有大约50万个换行符。然而,在用seq 3000000 >bigfile生成的文件上测试时,我得到了以下数字:

wc 0.425990104675
native 0.400163888931
iterate 3.10369205475

嘿,看,蟒蛇FTW!但是,使用较长的行(~70个字符(:

wc 1.60881590843
native 3.24313092232
iterate 4.92839002609

所以结论:这取决于情况,但wc似乎是最好的选择。

import subprocess
for f in files:
    subprocess.call(['wc', '-l', f])

还可以看看http://docs.python.org/library/subprocess.html#convenience-函数-例如,如果您想访问字符串中的输出,则需要使用subprocess.check_output()而不是subprocess.call()

无需使用wc -l使用以下python函数

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f, 1):
            pass
    return i

这可能比调用外部实用程序(以类似的方式在输入上循环(更有效。

更新

大错特错,wc -l比em>快很多!

seq 10000000 > huge_file
$ time wc -l huge_file 
10000000 huge_file
real    0m0.267s
user    0m0.110s
sys 0m0.010s
$ time ./p.py 
10000000
real    0m1.583s
user    0m1.040s
sys 0m0.060s

os.system获取一个字符串。只需显式构建字符串:

import os 
for i in files:
    os.system("wc -l " + i)

以下是我发现的解决此问题的Python方法:

count_of_lines_in_any_textFile = sum(1 for l in open('any_textFile.txt'))

我发现了一种更简单的方法:

import os
linux_shell='more /etc/hosts|wc -l'
linux_shell_result=os.popen(linux_shell).read()
print(linux_shell_result)

我的解决方案与lazyr的"原生"功能非常相似:

import functools
def file_len2(fname):
    with open(fname, 'rb') as f:
        lines= 0
        reader= functools.partial(f.read, 131072)
        for datum in iter(reader, ''):
            lines+= datum.count('n')
            last_wasnt_nl= datum[-1] != 'n'
        return lines + last_wasnt_nl

wc不同,这将以'\n'结尾的最后一行而非视为单独的一行。如果想要与wc相同的功能,那么它可以(非常不符合语法:(写成:

import functools as ft, itertools as it, operator as op
def file_len3(fname):
    with open(fname, 'rb') as f:
        reader= ft.partial(f.read, 131072)
        counter= op.methodcaller('count', 'n')
        return sum(it.imap(counter, iter(reader, '')))

在我生成的所有测试文件中具有与CCD_ 9相当的时间。

注意:这适用于Windows和POSIX机器。旧的MacOS使用'\r'作为行尾字符。

最新更新