1

この野蛮なスクリプトを作成して、文字列内の位置の可能なすべての組み合わせで n (最大 n=4) の $ を含む文字列の順列を作成しました。私は最終的に.replace('$','(\\w)')DNA検索シーケンスのミスマッチに使用します。スクリプトの書き方が原因で、一部の順列の $ の数は要求された数よりも少なくなっています。次に、それらを削除するスクリプトを作成しましたが、効果がないようで、削除スクリプトを実行するたびに、不要な順列がさらに削除されます。以下に貼り付けたコードでは、4 つの不一致がある単純なシーケンスで関数をテストしていることがわかります。次に、毎回削除される式の数をカウントする一連の削除スクリプトを実行します...私の経験では、ワイルドカード $ が 4 つ未満のすべての式を削除するには、約 8 回かかります。これについていくつか質問があります。

  1. 「n」個の不一致がある検索用の組み込み関数はありますか? 多分biopythonでも?これまでのところ、Paul_McGuire_regex 関数を見てきました:
    文字列の任意の場所で 1 つの不一致を許可する文字列を検索します
    これは、1 つの不一致しか生成しないようです。私は非常に新しいコーダーであるため、そのページの残りの関数のすべてのコードを完全に理解していないことを認めなければなりません。

  2. これは自分にとって良い練習になると思うので、このスクリプト全体を書くためのより良い方法はありますか?...Paul_McGuire_regex 関数を必要な回数だけ繰り返すことはできますか?

  3. 私にとって最も困惑しているのは、削除スクリプトが初めて 100% 機能しないのはなぜですか?

ご協力いただきありがとうございます。

def Mismatch(Search,n):
    List = []
    SearchL = list(Search)
    if n > 4:
        return("Error: Maximum of 4 mismatches")
    for i in range(0,len(Search)):
        if n == 1:
            SearchL_i = list(Search)
            SearchL_i[i] = '$'
            List.append(''.join(SearchL_i))
        if n > 1:
            for j in range (0,len(Search)):
                if n == 2:
                    SearchL_j = list(Search)
                    SearchL_j[i] = '$'
                    SearchL_j[j] = '$'
                    List.append(''.join(SearchL_j))
                if n > 2:
                    for k in range(0,len(Search)):
                        if n == 3:
                            SearchL_k = list(Search)
                            SearchL_k[i] = '$'
                            SearchL_k[j] = '$'
                            SearchL_k[k] = '$'
                            List.append(''.join(SearchL_k))
                        if n > 3:
                            for l in range(0,len(Search)):
                                if n ==4:
                                    SearchL_l = list(Search)
                                    SearchL_l[i] = '$'
                                    SearchL_l[j] = '$'
                                    SearchL_l[k] = '$'
                                    SearchL_l[l] = '$'
                                    List.append(''.join(SearchL_l))
    counter=0
    for el in List:
        if el.count('$') < n:
            counter+=1
            List.remove(el)
    return(List) 

List_RE = Mismatch('abcde',4)

counter = 0
for el in List_RE:
    if el.count('$') < 4:
        List_RE.remove(el)
        counter+=1

print("Filter2="+str(counter))
4

1 に答える 1

3

質問 1 に答えると、質問 2 と 3 を省略できますが、質問 3 を理解することが重要なので、まずそれを理解してから、完全に回避する方法を示します。

質問 3

質問 3 については、python でリストをループし、 loop 内で変更を加えると、ループするリストが変更されるためです。

制御フローに関するpythonドキュメントから(ステートメントセクション用)

ループ内で繰り返されるシーケンスを変更することは安全ではありません(これは、リストなどの変更可能なシーケンス タイプでのみ発生します)。

リストが で[a,b,c,d]あり、 でループするとしfor el in Listます。と言っelて、現在a、あなたはそうしますList.remove(el)

今、あなたのリストは[b,c,d]です。ただし、イテレータはリストの 2 番目の要素を指します (最初の要素が終了したため) c。本質的に、あなたはスキップしましbた。したがって、問題は、反復しているリストを変更していることです。

これを修正するにはいくつかの方法がありますList。複製するのに費用がかからない場合は、コピーを作成できます。したがって、繰り返しますList[:]が、から削除しListます。

しかし、常にコピーを作成するにはコストがかかるとしListます。次に、それを逆方向に繰り返します。reversed以下に注意してください。

for el in reversed(List):
    if el.count('$') < n:
        counter+=1
        List.remove(el)
return(List) 

上記の例で、 を逆方向に繰り返すとしListます。イテレータは から始まり、dに進みcます。を削除するcとしList=[a,b,d]ます。iterator はbackwardsを行っているため、今は element を指してbいるため、何もスキップしていません。

基本的に、これにより、まだ反復していないリストのビットを変更することを回避できます。

質問 1 & 2

私があなたの質問を正しく理解していれば、基本的には文字列 ( ) の長さである位置から選択nし、これらの位置のそれぞれに「$」を配置する必要があります。mmabcden

その場合、itertoolsモジュールを使用してそれを行うことができます。

import itertools
def Mismatch(Search,n):
    SearchL = list(Search)
    List     = [] # hold output
    # print list of indices to replace with '$'
    idxs = itertools.combinations(range(len(SearchL)),n)        
    # for each combination `idx` in idxs, replace str[idx] with '$':
    for idx in idxs:
        str = SearchL[:] # make a copy
        for i in idx:
            str[i]='$'
        List.append( ''.join(str) ) # convert back to string
    return List

これがどのように機能するか見てみましょう:

  1. 文字列をリストに変換してSearch反復できるようにし、空を作成Listして結果を保持します。
  2. idxs = itertools.combinations(range(len(SearchL)),n)「セット内の長さ n のすべてのサブセットを検索します[0,1,2,3,...,length-of-search-string -1]。試してください。

    idxs = itertools.combinations(range(5),4)
    for idx in idxs: 
        print idx
    

    私が何を意味するかを見るために。

  3. の各要素idxsは、n0 からlen(SearchL)-1(たとえば. の i 番目の文字をタプルのそれぞれの '$' に(0,1,2,4)置き換えます。SearchLi
  4. 結果を文字列に戻し、 に追加しListます。

例として:

Mismatch('abcde',3)
['$$$de', '$$c$e', '$$cd$', '$b$$e', '$b$d$', '$bc$$', 'a$$$e', 'a$$d$', 'a$c$$', 'ab$$$']
Mismatch('abcde',4) # note, the code you had made lots of duplicates.
['$$$$e', '$$$d$', '$$c$$', '$b$$$', 'a$$$$'] 
于 2011-12-14T23:41:43.247 に答える