Python производительность с заменой, которая редко заменяет - PullRequest
0 голосов
/ 16 апреля 2020

Я пишу список строк в виде файла с разделителями табуляции, используя python 3.6

Редко, но гипотетически возможно, что в данных есть вкладки. Если это так, мне нужно заменить их пробелами. Вот что я делаю так:

row = [x.replace("\t", " ") for x in row]

Проблема в том, что эта строка отвечает за примерно 1/4 времени выполнения всей программы, и она практически никогда ничего не делает.

Есть ли более быстрый способ удалить вкладки из моих данных?

Есть ли способ воспользоваться тем, что у него, вероятно, нет вкладок?

У меня есть пытался работать в байтах вместо строк, и это не имело никакого значения.

Ответы [ 2 ]

3 голосов
/ 16 апреля 2020

Я испробовал различные подходы, и самый быстрый - выполнить условную замену в индексах, где есть вкладка

def testReplace(sList):
    return [s.replace("\t"," ") for s in sList]

noTabs  = str.maketrans("\t"," ")
def testTrans(sList):
    return [s.translate(noTabs) for s in sList]

def joinSplit(sList):
    return "\n".join(sList).replace("\t"," ").split("\n")

def conditional(sList):
    result = sList.copy() # not needed if you intend to replace the list
    for i,s in enumerate(sList):
        if "\t" in s:
            result[i] = s.replace("\t"," ")
    return result

проверки производительности:

from timeit import timeit
count   = 100
strings = ["Hello World"*10]*1000  # ["Hello \t World"*10]*1000

t = timeit(lambda:testReplace(strings),number=count)
print("replace",t)   

t = timeit(lambda:testTrans(strings),number=count)
print("translate",t) 

t = timeit(lambda:joinSplit(strings),number=count)
print("joinSplit",t) 

t = timeit(lambda:conditional(strings),number=count)
print("conditional",t)

вывод:

# With tabs
replace     0.03365320100000002
translate   0.08165113099999993
joinSplit   0.027709890000000015
conditional 0.007067911000000038

# without tabs
replace     0.015160736000000008
translate   0.07439537500000004
joinSplit   0.017001820000000056
conditional 0.0065534649999999806
1 голос
/ 16 апреля 2020

Не проверено на вопрос производительности, но я бы использовал модуль csv, который знает о полях, содержащих новые строки или разделители, и автоматически цитирует их:

import csv

with open(filename, 'w', newline='') ad fd:
    wr = csv.writer(fd, delimiter='\t')
    ...
        wr.writerow(row)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...