在python中获取第一个和第二个管道之间的数据

2024-10-01 04:59:46 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的样本数据

78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193

我想得到的结果是

^{pr2}$

目前我正在字符串上使用split并访问该值。但我想用正则表达式。在

需要注意的一些条件: 数据可能为空 数据将不包含管道(|)

我想用regex而不是split,因为我认为regex更有效。我希望它尽可能高效的原因是源文件70gb。在

编辑:

这是我将要使用的全部代码

def main(argv):
    mylist = set();
    input_file = open("test.txt", 'r')

    for row in input_file:
        rowsplit = row.split("|");

        if rowsplit[1] !='':
            if rowsplit[1] in mylist:
                filename= "bby_"+rowsplit[1]+".dat";
                existingFile=open(filename,'a')
                existingFile.write(row);
                existingFile.close()
            else:
                mylist.add(rowsplit[1])
                filename= "bby_"+rowsplit[1]+".dat";
                newFile = open(filename,'a')
                newFile.write(row);
                newFile.close();
        else:
            print "Empty"
    print mylist

我只是不知道该用哪一个答案:(

我只想让代码快点。就这样。在


Tags: 数据代码ininputifopenfilenameregex
3条回答

下面是python3.4.3上有意义的答案的性能:

In [4]: timeit.timeit('s.split("|", 2)[1]', 's = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"')
Out[4]: 0.43930888699833304

In [10]: timeit.timeit('re.search(r"^[^a-zA-Z]*([a-zA-Z]+)", s).group(1)', 's = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"; import re')
Out[10]: 1.234878903022036

In [16]: timeit.timeit('re.search("^\d*\|(\w+?)?\|", s).group(1)', 's = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"; import re')
Out[16]: 1.8305770770530216

如果没有管道:

^{pr2}$

我想你可以在:Python: Split string by list of separators找到你的答案

def split(txt, seps):
    default_sep = seps[0]

    # we skip seps[0] because that's the default seperator
    for sep in seps[1:]:
        txt = txt.replace(sep, default_sep)

    return [i.strip() for i in txt.split(default_sep)]

Joschua(回答上述问题的用户)进行了测试,结果regex的效率更高。

拆分和检查长度可能仍然比正则表达式快:

for line in f:
    spl = line.split("|",2)
    if len(spl) > 2:
        print(spl[1])
       ....

匹配和非匹配行上的一些计时:

^{pr2}$

您可以通过创建一个本地引用结构分裂公司名称:

_spl = str.split
for line in f:
    spl = _spl(s,"|",2)
    if len(spl) > 2:
      .....

由于每条管线中的管道数量始终相同:

def main(argv):
    seen = set() # only use if you actually need  a set of all names
    with open("test.txt", 'r') as infile:
        r = csv.reader(infile, delimiter="|")
        for row in r:
            v = row[1]
            if v:
                filename = "bby_" + v + ".dat"
                existingFile = open(filename, 'a')
                existingFile.write(row)
                existingFile.close()
                seen.add(v)
            else:
                print "Empty"

如果/else在您附加到文件时显得多余,不管怎样,如果您想保留一组行[1]的另一个原因,您可以每次都添加到该集合中,除非您确实想要一组所有的名称,否则我会从代码中删除它。

应用相同的逻辑进行拆分:

def main(argv):
    seen = set()
    with open("test.txt", 'r') as infile:
        _spl = str.split
        for row in infile:
            v = _spl(row,"|",2)[1]
            if v:
                filename = "bby_" + v + ".dat"
                existingFile = open(filename, 'a')
                existingFile.write(row)
                existingFile.close()
                seen.add(v)
            else:
                print "Empty"

会导致大量开销的是不断地打开和写入,但是除非您可以将所有行存储在内存中,否则没有简单的方法来绕过它。

就阅读而言,在一个1000万行的文件中,只需拆分两倍就可以比csv阅读器表现出色:

In [15]: with open("in.txt") as f:
   ....:     print(sum(1 for _ in f))
   ....: 
10000000

In [16]: paste
def main(argv):
    with open(argv, 'r') as infile:
        for row in infile:
            v = row.split("|", 2)[1]
            if v:
                pass
## -- End pasted text --

In [17]: paste
def main_r(argv):
    with open(argv, 'r') as infile:
        r = csv.reader(infile, delimiter="|")
        for row in r:
            if row[1]:
                pass

## -- End pasted text --

In [18]: timeit main("in.txt")
1 loops, best of 3: 3.85 s per loop

In [19]: timeit main_r("in.txt")
1 loops, best of 3: 6.62 s per loop

相关问题 更多 >