2013-02-28 3 views
0

Я читаю файл CSV через csv.reader(), я хочу прочитать значения свободных от всякого рода символ или пробел и в нижнем регистре, как:Как удалить все символы и пробелы из строки?

a = " Kingston-(USB) = 1GB, 2GB, 32GB . . . " 

новообращенный «а», как это:

a = "kingstonusb1gb2gb32gb" 

Мне просто нужны алфавиты и цифры в моих данных.
Символ любого вида должен быть удален.
Я использовал .lower() функция и .strip() функция для этого. но функция strip просто удаляет пробелы между словами, тогда как я хочу удалить все виды символов.
Спасибо.

ответ

3

Вы можете использовать регулярное выражение:

>>> import re 
>>> a = " Kingston-(USB) = 1GB, 2GB, 32GB . . . " 
>>> re.sub(r'[^a-z0-9]', '', a.lower()) 
'kingstonusb1gb2gb32gb' 

или генератор:

>>> import string 
>>> allowed = string.lowercase + string.digits 
>>> ''.join(c for c in a.lower() if c in allowed) 
'kingstonusb1gb2gb32gb' 

Или что-то быстро:

>>> import string 
>>> allowed = set(string.lowercase + string.digits) 
>>> ''.join(filter(allowed.__contains__, a.lower())) 
'kingstonusb1gb2gb32gb' 
+0

Я побил вас генератору - и моя работает в O (N), а не O (N^2) ;-) – mgilson

+0

@mgilson: Dang it. Ну, посмотри мое редактирование. – Blender

+0

:) - да да ... +1 – mgilson

2

я бы, вероятно, сделать что-то вроде:

import string 
good = set(string.ascii_lowercase + string.digits) 
a = ''.join(x for x in a.lower() if x in good) 

Это, вероятно, не самый эффективный, но он должен работать, и это довольно легко читать/понять.

+0

+1 Есть ли разница между 'ascii_lowercase' и' string.lowercase'? – Blender

+0

@Blender - 'ascii_lowercase' не зависит от локали. – mgilson

3

Если вы используете ASCII, вы можете использовать str.translate удалить все без цифр и альфа из строчки нижнего регистра

>>> from string import ascii_letters, digits 
>>> ascii = set(chr(e) for e in range(128)) 
>>> ascii_sans_alpha = ''.join(ascii.difference(ascii_letters + digits)) 
>>> a = " Kingston-(USB) = 1GB, 2GB, 32GB . . . " 
>>> a.lower().translate(None,ascii_sans_alpha) 
'kingstonusb1gb2gb32gb' 

И как быстро это? Использовать ссылку на время

>>> def mgilson(a, good = set(string.ascii_lowercase + string.digits)): 
    return ''.join(x for x in a.lower() if x in good) 

>>> def blender_re(a): 
    return re.sub(r'[^a-z0-9]', '', a.lower()) 

>>> def blender_gen(a, allowed = string.lowercase + string.digits): 
    return ''.join(c for c in a.lower() if c in allowed) 

>>> def blender_fast(a, allowed = set(string.lowercase + string.digits)): 
    return ''.join(filter(allowed.__contains__, a.lower())) 

>>> def abhijit(a, ascii_sans_alpha = ''.join(set(chr(e) for e in range(128)).difference(ascii_letters + digits))): 
    return a.lower().translate(None,ascii_sans_alpha) 

>>> time_dict = {"abhijit": "from __main__ import string, a", 
      "blender_re":"from __main__ import re, a, abhijit", 
      "blender_gen": "from __main__ import string, a", 
      "blender_fast": "from __main__ import string, a", 
      "mgilson": "from __main__ import string, a"} 
>>> for k, v in time_dict.items(): 
    t = timeit.Timer(stmt="{}(a)".format(k),setup = "{},{}".format(v,k)) 
    print "Timing for {} is {}".format(k, t.timeit(100000)) 


Timing for blender_fast is 0.573348026237 
Timing for blender_re is 0.632169556846 
Timing for blender_gen is 0.720916486331 
Timing for mgilson is 0.586592185393 
Timing for abhijit is 0.203489867547 
>>> 
+0

Но мои ручки unicode 'abhijit (u'señor ')';) – Blender

+0

Я думал о 'translate' .. но это казалось грязным, поэтому я не беспокоился. Я рад, что ты это сделал. – mgilson

Смежные вопросы