Сделать цикл Python быстрее - PullRequest
0 голосов
/ 08 мая 2018

Можно ли сделать эту маленькую рутину быстрее? С elif's это делает понимание выходящим из-под контроля, но, возможно, я не пробовал это правильно.

def cleanup(s):
    strng = ''
    good = ['\t', '\r', '\n']
    for char in s:        
        if unicodedata.category(char)[0]!="C":
            strng += char
        elif char in good:
            strng += char
        elif char not in good:
            strng += ' '
    return strng

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Если я правильно понимаю, вы хотите преобразовать все управляющие символы Unicode в пробел, кроме tab , возврат каретки и новая строка . Для этого вы можете использовать str.translate:

good = map(ord, '\t\r\n')
TBL_CONTROL_TO_SPACE = {
    i: u' '
    for i in xrange(sys.maxunicode)
    if unicodedata.category(unichr(i))[0] == "C" and i not in good
}

def cleanup(s):
    return s.translate(TBL_CONTROL_TO_SPACE)
0 голосов
/ 08 мая 2018

Если я правильно понимаю вашу задачу, вы хотите заменить все управляющие символы Юникода пробелами , за исключением \t, \n и \r.

Вот как это сделать более эффективно с помощью регулярных выражений вместо циклов.

import re

# make a string of all unicode control characters 
# EXCEPT \t - chr(9), \n - chr(10) and \r - chr(13)
control_chars = ''.join(map(unichr, range(0,9) + \
                            range(11,13) + \
                            range(14,32) + \
                            range(127,160)))

# build your regular expression
cc_regex = re.compile('[%s]' % re.escape(control_chars))

def cleanup(s):
    # substitute all control characters in the regex 
    # with spaces and return the new string
    return cc_regex.sub(' ', s)

Вы можете управлять тем, какие символы включать или исключать, манипулируя диапазонами, составляющими переменную control_chars. См. Список символов Unicode .

РЕДАКТИРОВАТЬ : Результаты синхронизации.

Просто из любопытства я провел несколько временных тестов, чтобы выяснить, какой из трех существующих методов самый быстрый.

Я сделал три метода с именем cleanup_op(s), который был копией кода OP; cleanup_loop(s) что является ответом Кристиана Чиупиту; cleanup_regex(s) это мой код.

Вот что я пробежал:

from timeit import default_timer as timer

sample = u"this is a string with some characters and \n new lines and \t tabs and \v and other stuff"*1000

start = timer();cleanup_op(sample);end = timer();print end-start
start = timer();cleanup_loop(sample);end = timer();print end-start
start = timer();cleanup_regex(sample);end = timer();print end-start

Результаты:

cleanup_op завершено примерно через 1,1 секунды

cleanup_loop завершено примерно через 0,02 секунды

cleanup_regex завершено примерно за 0,004 секунды

Итак, любой из ответов является значительным улучшением по сравнению с исходным кодом. Я думаю, что @CristianCiupitu дает более элегантный и питонический ответ, в то время как регулярное выражение все еще быстрее.

...