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

cra*_*liv 9 python

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

import os 
for i in files:
    os.system("wc -l <insert filename>").
Run Code Online (Sandbox Code Playgroud)

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

Lau*_*low 11

让我们比较一下:

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
Run Code Online (Sandbox Code Playgroud)

去时间功能!

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)
Run Code Online (Sandbox Code Playgroud)

结果:

wc 1.25185894966
native 2.47028398514
iterate 2.40715694427
Run Code Online (Sandbox Code Playgroud)

因此,wc在150 MB压缩文件上的速度大约是其速度的两倍,其中包含大约500 000个换行符,这就是我测试的内容.但是,测试生成的文件seq 3000000 >bigfile,我得到这些数字:

wc 0.425990104675
native 0.400163888931
iterate 3.10369205475
Run Code Online (Sandbox Code Playgroud)

嘿看,python FTW!但是,使用更长的线(~70个字符):

wc 1.60881590843
native 3.24313092232
iterate 4.92839002609
Run Code Online (Sandbox Code Playgroud)

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


Thi*_*ter 7

import subprocess
for f in files:
    subprocess.call(['wc', '-l', f])
Run Code Online (Sandbox Code Playgroud)

另请查看http://docs.python.org/library/subprocess.html#convenience-functions - 例如,如果要访问字符串中的输出,则需要使用subprocess.check_output()而不是subprocess.call()

  • 在 Python 中获取文件行数的单行代码: `int(subprocess.check_output(["wc", "-l", fname]).decode("utf8").split()[0])` (2认同)

Fre*_*ihl 5

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

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f, 1):
            pass
    return i
Run Code Online (Sandbox Code Playgroud)

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

更新

完全错误的,wc -l很多快!

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
Run Code Online (Sandbox Code Playgroud)