Каков самый эффективный путь в Python для преобразования строки в весь нижний регистр, снимающий все альфа-символы неASCII?

Это потому, что вкладка - это именование контейнера, а ваше обновление должно быть update="Search:insTable:display". Что вы можете сделать, просто разместите свое диалоговое окно вне формы и все еще внутри вкладки, тогда оно будет: update="Search:display"

28
задан grieve 13 March 2009 в 00:51
поделиться

10 ответов

Другое решение (не, что pythonic, но очень быстро) состоит в том, чтобы использовать string.translate - хотя примечание, что это не будет работать на unicode. Также стоит отметить, что можно ускорить код Dana путем перемещения символов в набор (который ищет хешем, вместо того, чтобы выполнить линейный поиск каждый раз). Вот синхронизации, которые я получаю для различных из данных решений:

import string, re, timeit

# Precomputed values (for str_join_set and translate)

letter_set = frozenset(string.ascii_lowercase + string.ascii_uppercase)
tab = string.maketrans(string.ascii_lowercase + string.ascii_uppercase,
                       string.ascii_lowercase * 2)
deletions = ''.join(ch for ch in map(chr,range(256)) if ch not in letter_set)

s="A235th@#$&( er Ra{}|?>ndom"

# From unwind's filter approach
def test_filter(s):
    return filter(lambda x: x in string.ascii_lowercase, s.lower())

# using set instead (and contains)
def test_filter_set(s):
    return filter(letter_set.__contains__, s).lower()

# Tomalak's solution
def test_regex(s):
    return re.sub('[^a-z]', '', s.lower())

# Dana's
def test_str_join(s):
    return ''.join(c for c in s.lower() if c in string.ascii_lowercase)

# Modified to use a set.
def test_str_join_set(s):
    return ''.join(c for c in s.lower() if c in letter_set)

# Translate approach.
def test_translate(s):
    return string.translate(s, tab, deletions)


for test in sorted(globals()):
    if test.startswith("test_"):
        assert globals()[test](s)=='atherrandom'
        print "%30s : %s" % (test, timeit.Timer("f(s)", 
              "from __main__ import %s as f, s" % test).timeit(200000))

Это дает мне:

               test_filter : 2.57138351271
           test_filter_set : 0.981806765698
                test_regex : 3.10069885233
             test_str_join : 2.87172979743
         test_str_join_set : 2.43197956381
            test_translate : 0.335367566218

[Редактирование], Обновленное с решениями для фильтра также. (Отметьте то использование set.__contains__ имеет большое значение здесь, поскольку это старается не делать дополнительный вызов функции для лямбды.

25
ответ дан Community 28 November 2019 в 02:35
поделиться

Подобный @Dana, но я думаю, что это походит на задание фильтрации, и это должно быть видимо в коде. Также без потребности явно звонить join():

def strip_string_to_lowercase(s):
  return filter(lambda x: x in string.ascii_lowercase, s.lower())
4
ответ дан unwind 14 October 2019 в 09:53
поделиться

Не особенно эффективное время выполнения, но конечно более хорошее на плохих, усталых глазах кодера:

def strip_string_and_lowercase(s):
    return ''.join(c for c in s.lower() if c in string.ascii_lowercase)
11
ответ дан SilentGhost 14 October 2019 в 09:53
поделиться

Лично я использовал бы регулярное выражение и затем преобразовал бы заключительную строку в нижний регистр. Я понятия не имею, как записать это в Python, но основная идея к:

  1. символы Remove в строке, которые не соответствуют нечувствительному к регистру regex" \w"
  2. , Преобразовывают строку в нижний регистр

или наоборот.

0
ответ дан Acumenus 14 October 2019 в 09:53
поделиться
>>> filter(str.isalpha, "This is a Test").lower()
'thisisatest'
>>> filter(str.isalpha, "A235th@#$&( er Ra{}|?>ndom").lower()
'atherrandom'
17
ответ дан A. Coady 28 November 2019 в 02:35
поделиться

Я был бы:

  • нижний регистр строка
  • замените все [^a-z] с ""

Как этот:

def strip_string_to_lowercase():
  nonascii = re.compile('[^a-z]')
  return lambda s: nonascii.sub('', s.lower().strip())

Править: Оказывается, что исходная версия (ниже) является действительно медленной, хотя некоторая производительность может быть получена путем преобразования его в закрытие (выше).

def strip_string_to_lowercase(s):
  return re.sub('[^a-z]', '', s.lower().strip())

Мои измерения производительности с 100 000 повторений против строки

"A235th@#$&( er Ra{}|?>ndom"

показанный, что:

  • f_re_0 took 2672.000 ms (это - исходная версия этого ответа),
  • f_re_1 took 2109.000 ms (это - версия закрытия, показанная выше),
  • f_re_2 took 2031.000 ms (версия закрытия, без избыточного strip())
  • f_fl_1 took 1953.000 ms (неветер filter/lambda версия)
  • f_fl_2 took 1485.000 ms (Coady filter версия)
  • f_jn_1 took 1860.000 ms (Dana join версия)

Ради теста я не сделал print результаты.

8
ответ дан Community 28 November 2019 в 02:35
поделиться

Python 2.x translate метод

Преобразуйте в нижний регистр и отфильтруйте неальфа-символы неASCII:

from string import ascii_letters, ascii_lowercase, maketrans

table = maketrans(ascii_letters, ascii_lowercase*2)
deletechars = ''.join(set(maketrans('','')) - set(ascii_letters))

print "A235th@#$&( er Ra{}|?>ndom".translate(table, deletechars)
# -> 'atherrandom'

Python 3 translate метод

НеASCII фильтра:

ascii_bytes = "A235th@#$&(٠٫٢٥ er Ra{}|?>ndom".encode('ascii', 'ignore')

Использовать bytes.translate() преобразовать в нижний регистр и удалить неальфа-байты:

from string import ascii_letters, ascii_lowercase

alpha, lower = [s.encode('ascii') for s in [ascii_letters, ascii_lowercase]]
table = bytes.maketrans(alpha, lower*2)           # convert to lowercase
deletebytes = bytes(set(range(256)) - set(alpha)) # delete nonalpha

print(ascii_bytes.translate(table, deletebytes))
# -> b'atherrandom'
6
ответ дан jfs 28 November 2019 в 02:35
поделиться

Я добавил решения для фильтра кода Brian:

import string, re, timeit

# Precomputed values (for str_join_set and translate)

letter_set = frozenset(string.ascii_lowercase + string.ascii_uppercase)
tab = string.maketrans(string.ascii_lowercase + string.ascii_uppercase,
                       string.ascii_lowercase * 2)
deletions = ''.join(ch for ch in map(chr,range(256)) if ch not in letter_set)

s="A235th@#$&( er Ra{}|?>ndom"

def test_original(s):
    tmpStr = s.lower().strip()
    retStrList = []
    for x in tmpStr:
        if x in string.ascii_lowercase:
            retStrList.append(x)

    return ''.join(retStrList)


def test_regex(s):
    return re.sub('[^a-z]', '', s.lower())

def test_regex_closure(s):
  nonascii = re.compile('[^a-z]')
  def replacer(s):
    return nonascii.sub('', s.lower().strip())
  return replacer(s)


def test_str_join(s):
    return ''.join(c for c in s.lower() if c in string.ascii_lowercase)

def test_str_join_set(s):
    return ''.join(c for c in s.lower() if c in letter_set)

def test_filter_set(s):
    return filter(letter_set.__contains__, s.lower())

def test_filter_isalpha(s):
    return filter(str.isalpha, s).lower()

def test_filter_lambda(s):
    return filter(lambda x: x in string.ascii_lowercase, s.lower())

def test_translate(s):
    return string.translate(s, tab, deletions)

for test in sorted(globals()):
    if test.startswith("test_"):
        print "%30s : %s" % (test, timeit.Timer("f(s)", 
              "from __main__ import %s as f, s" % test).timeit(200000))

Это дает мне:

       test_filter_isalpha : 1.31981746283
        test_filter_lambda : 2.23935583992
           test_filter_set : 0.76511679557
             test_original : 2.13079176264
                test_regex : 2.44295629752
        test_regex_closure : 2.65205913042
             test_str_join : 2.25571266739
         test_str_join_set : 1.75565888961
            test_translate : 0.269259640541

Кажется, что isalpha использует подобный алгоритм, по крайней мере, с точки зрения O (), к алгоритму набора.


Править: Добавленный набор фильтра, и переименованный в фильтр функционирует, чтобы быть немного более ясным.

3
ответ дан grieve 28 November 2019 в 02:35
поделиться

Это - типовое приложение списка compehension:

import string
s = "O235th@#$&( er Ra{}|?<ndom"
print ''.join(c for c in s.lower() if c in string.ascii_lowercase)

Это не отфильтрует" <" (объект HTML), как в Вашем примере, но я предполагаю, что это было случайным сокращением и прошлой проблемой.

2
ответ дан Ber 28 November 2019 в 02:35
поделиться
>>> import string
>>> a = "O235th@#$&( er Ra{}|?&lt;ndom"
>>> ''.join(i for i in a.lower() if i in string.ascii_lowercase)
'otheraltndom'

выполнение по существу того же как Вы.

2
ответ дан SilentGhost 28 November 2019 в 02:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: