循环遍历文件时索引超出范围错误

时间:2017-11-20 16:56:22

标签: python python-3.x

我需要创建一个脚本,将一个包含md5列表的文本文件解析为哈希值。我的脚本适用于小文件,但在谈到包含数百万行的列表时,我接收IndexError: list index out of rangeMemoryError。我尝试过字典,但没有运气。作为参考,我使用了这篇文章中的信息:How do you read a file into a list in Python?

示例文件结构(文件包含10mln行):

00003b63ee5e47514964167709ba60df:ainazulaikha
00004ae02a3cf46250ef834f7b75bb91:78836896hxy7
000066b871abdafac2052532ab9da827:nihao1314521+
0000721897d675d6ac0198ad19d48f21:y138636812709
00008f46c906349f1df99ccdea4104a1:sikaozhanche123
000093856b4e947511870f3e10464129:646434
00009ad044e03d0359e8065a0334a046:LiuYi20011105
0000a4bed6b4a1a6fa96a54ca906e1bd:chiaochiao0520

我的脚本(用于测试目的):

with open('C:/Users/Admin/Downloads/106_17-media_found_hash_plain.txt', 'r') as f:
    string = '00008f46c906349f1df99ccdea4104a1'
    for line in f:
        reg = re.findall("^'?([0-9A-Fa-f]{32})'?:'?([^\s]+)'?", line)
        if string in reg[0][0]:
            print('ok')

3 个答案:

答案 0 :(得分:0)

首先,reg = re.findall(可以返回一个空列表,因此在执行

之前测试列表是否包含某些内容
if string in reg[0][0]:

我建议:

if reg and reg[0] and string in reg[0][0]:

然后,如果您遇到超过python内存的veeeery长行,则会发生内存错误 。不太可能,但是如果文件损坏/生成过程“忘记”暂时发布换行符就可以完成,在这种情况下你必须修改输入,否则代码将变得非常复杂。

答案 1 :(得分:0)

您的标题,说明和实际代码指向了近3个不同的方向,但假设您只是在寻找string,您可以这样做:

with open('C:/Users/Admin/Downloads/106_17-media_found_hash_plain.txt', 'r') as f:
    string = '00008f46c906349f1df99ccdea4104a1'
    for line in f:
        if line.startswith(string):
            print('Gotcha! {}'.format(line))

可能需要一段时间但你永远不会耗尽内存(没有存储任何东西)也不会得到IndexError

答案 2 :(得分:0)

在字符串中搜索子字符串的最简单方法是使用方法if substring in string。您可以使用re执行此操作,但效率要低得多。我有几种方法可以证明这一点:

with open('test.txt') as f:
    data = f.readlines()

string = '00008f46c906349f1df99ccdea4104a1'


def func_1(data, string):

    for line in data:
        if re.match(string, line) is not None:
            pass
    return


def func_2(data, string):

    for line in data:
        if re.search(string, line) is not None:
            pass
    return


def func_3(data, string):

    for line in data:
        if string in line:
            pass
    return


def func_4(data, string):

    for line in data:
        if line.startswith(string):
            pass
    return


def func_5(data, string):

    def thing(line):
        string = '00008f46c906349f1df99ccdea4104a1'
        if string in line:
            pass
        return

    map(thing, data)

    return


def func_6(data, string):

    data = [line.split(':')[0] for line in data]

    if string in data:
        pass

    return

结果:

--------------------
100  iterations
--------------------

func_1: 0.579837208991
func_2: 0.89487306496
func_3: 0.0426233092805
func_4: 0.0963648696288
func_5: 0.113332976336
func_6: 0.10395732091

--------------------
1000  iterations
--------------------

func_1: 5.49227099705
func_2: 5.43578546216
func_3: 0.457362410806
func_4: 0.971125123276
func_5: 1.00572267516
func_6: 1.00902133508

--------------------
10000  iterations
--------------------

func_1: 61.2676211896
func_2: 61.2018943197
func_3: 4.1501189249
func_4: 9.45583133638
func_5: 9.94970703866
func_6: 10.0233565828

*我的测试文件包含4472行。