簡體   English   中英

使用Python只保留字符串中的某些字符?

[英]Keeping only certain characters in a string using Python?

在我的程序中,我有一個這樣的字符串:

ag ct oso gcota

使用python,我的目標是擺脫空白區域,只保留a,t,c和g字符。 我理解如何擺脫空白區域(我只是使用line = line.replace(“”,“”))。 但是,如果它們可能是字母表中的任何其他字母,我怎么能擺脫我不需要的字符呢?

一種非常優雅和快速的方法是使用正則表達式:

import re

str = 'ag ct oso gcota'
str = re.sub('[^atcg]', '', str)

"""str is now 'agctgcta"""

我可能會這樣做:

chars_i_want = set('atcg')
final_string = ''.join(c for c in start_string if c in chars_i_want)

這可能是最簡單的方法。


另一個選擇是使用str.translate來完成工作:

import string
chars_to_remove = string.printable.translate(None,'acgt')
final_string = start_string.translate(None,chars_to_remove)

我不確定哪個會表現得更好。 它需要通過timeit定時才能明確地知道。


更新 :時間!

import re
import string

def test_re(s,regex=re.compile('[^atgc]')):
    return regex.sub(s,'')

def test_join1(s,chars_keep=set('atgc')):
    return ''.join(c for c in s if c in chars_keep)

def test_join2(s,chars_keep=set('atgc')):
    """ list-comp is faster, but less 'idiomatic' """
    return ''.join([c for c in s if c in chars_keep])

def translate(s,chars_to_remove = string.printable.translate(None,'acgt')):
    return s.translate(None,chars_to_remove)

import timeit

s = 'ag ct oso gcota'
for func in "test_re","test_join1","test_join2","translate":
    print func,timeit.timeit('{0}(s)'.format(func),'from __main__ import s,{0}'.format(func))

可悲的是(對我來說), regex贏得了我的機器:

test_re 0.901512145996
test_join1 6.00346088409
test_join2 3.66561293602
translate 1.0741918087

在upvoting之前,人們是否測試了mgilson的test_re()函數? re.sub()的參數是相反的,所以它在空字符串中進行替換,並且總是返回空字符串。

我在python 3.4中工作; string.translate()只接受一個參數,一個字典。 因為構建這個dict有開銷,所以我把它移出了函數。 公平地說,我還將正則表達式編譯移出了函數(這沒有明顯的區別)。

import re
import string

regex=re.compile('[^atgc]')

chars_to_remove = string.printable.translate({ ord('a'): None, ord('c'): None, ord('g'): None, ord('t'): None })
cmap = {}
for c in chars_to_remove:
    cmap[ord(c)] = None

def test_re(s):
    return regex.sub('',s)

def test_join1(s,chars_keep=set('atgc')):
    return ''.join(c for c in s if c in chars_keep)

def test_join2(s,chars_keep=set('atgc')):
    """ list-comp is faster, but less 'idiomatic' """
    return ''.join([c for c in s if c in chars_keep])

def translate(s):
    return s.translate(cmap)

import timeit

s = 'ag ct oso gcota'
for func in "test_re","test_join1","test_join2","translate":
    print(func,timeit.timeit('{0}(s)'.format(func),'from __main__ import s,{0}'.format(func)))

以下是時間安排:

test_re 3.3141989699797705
test_join1 2.4452173250028864
test_join2 2.081048655003542
translate 1.9390292020107154

這太糟糕了,string.translate()沒有選項來控制如何處理不在地圖中的字符。 當前的實現是保留它們,但是我們也可以選擇刪除它們,如果我們想要保留的字符遠遠少於我們要刪除的字符(哦,你好,unicode)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM