python 的in 和 find 执行效率问题

发布于 2022-09-03 11:46:35 字数 2002 浏览 11 评论 0

if info_list[key] in content:
if content.find(info_list[key]) != -1

这两个查找字符串的效率差异。

bb.txt 5G 的文件,前者跑了 8 小时,find 跑了 20 小时。

汗!! 有没有更快捷的方法?

#coding:utf-8
import os
import sys

def getList(filename) :
    fp = open(filename, 'r')
    info_list = {}
    for line in open(filename):
        line = fp.readline()
        tmp = line.strip('\n').split('\t')
        info_list[tmp[0]] = tmp[1]
    fp.close()
    return info_list


def matchname(info_list, input_file, output_file) : 
    fp = open(input_file, 'r')
    fw = open(output_file, 'a')
    for line in open(input_file):
        line = fp.readline()
        tmp = line.strip('\n').split('\t')
        content = tmp[2]
        for key in info_list:
            if info_list[key] in content:
            #if content.find(info_list[key]) != -1 :
                result = tmp[0] + '\t' + tmp[1] + '\t' +  info_list[key] + '\t'  + key + '\n'
                fw.write(result)
            else :
                continue
    fw.close()
    fp.close()

if __name__ == '__main__':
    # date=sys.argv[1]
    info_filename = 'aa.txt'
    content_filename = 'bb.txt'
    result_filename = 'final_output2.txt'
    info_list = getList(info_filename)
    matchname(info_list, content_filename, result_filename)
    print('done...')
a@bj-m-20a:~/study/python_learn$ cat aa.txt
aaa    赵六
bbb    赵四
ccc    李丽
ddd    吴小龙
a@bj-m-20a:~/study/python_learn$ cat bb.txt
001    0001    李丽你好啊李丽是个大美女
002    0002    赵四家的后厨赵六你是我的爱
003    0003    吴小龙上次数学考的不及格
a@bj-m-20a:~/study/python_learn$ cat final_output2.txt
001    0001    李丽    ccc
001    0001    李丽    ccc
002    0002    赵六    aaa
002    0002    赵四    bbb
003    0003    吴小龙    ddd
001    0001    李丽    ccc
002    0002    赵六    aaa
002    0002    赵四    bbb
003    0003    吴小龙    ddd

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笔芯 2022-09-10 11:46:35

改了一下你的代碼, 這樣應該比較簡潔:

(根據 @依云 的建議又改了一下)

import os
import sys

def getinfo(filename) :
    info = {}
    with open(filename, 'r') as f:
        for line in f:
            ID, name = line.strip().split()
            info[ID] = name
    return info


def matchname(info, input_file, output_file) : 
    with open(input_file, 'r') as reader, open(output_file, 'w') as writer:
        for line in reader:
            n1, n2, content = line.strip().split()
            for ID, name in info.items():
                if name in content:
                    print(n1, n2, name, ID, sep='\t', file=writer)


if __name__ == '__main__':
    info_filename = 'aa.txt'
    content_filename = 'bb.txt'
    result_filename = 'final_output2.txt'
    info = getinfo(info_filename)
    matchname(info, content_filename, result_filename)
    print('done')

(稍後回來補說明...)


我回答過的問題: Python-QA

写给空气的情书 2022-09-10 11:46:35

in 当然比 find 快,因为前者比后者少了次属性查找、函数调用,多了次比较操作:

>>> def t():
...   return "abctestdef".find("testx")
... 
>>> import dis
>>> dis.dis(t)
  2           0 LOAD_CONST               1 ('abctestdef')
              3 LOAD_ATTR                0 (find)
              6 LOAD_CONST               2 ('testx')
              9 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             12 RETURN_VALUE
>>> def t():
...   return "test" in "abctestdef"
... 
>>> dis.dis(t)
  2           0 LOAD_CONST               1 ('test')
              3 LOAD_CONST               2 ('abctestdef')
              6 COMPARE_OP               6 (in)
              9 RETURN_VALUE

想要更快,可以考虑使用 Rust :-)

另外你的代码写得不太好。文件操作建议使用 with 而不是手动关闭。

耳钉梦 2022-09-10 11:46:35

set的in时间复杂度是O(1)
list的in时间复杂度是O(n)

你可以在组装的时候尝试使用集合

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文