6

文字列のn番目の文字をすべて置き換える関数を書いています

def replaceN(str, n):
   for i in range(len(str)):
     n=str[i]
     newStr=str.replace(n, "*")
     return newStr

しかし、実行すると、最初の文字だけが * に置き換えられます。間違いがあると確信していますが、私には見えません。

4

7 に答える 7

10

一発ギャグ:

newstring = ''.join("*" if i % n == 0 else char for i, char in enumerate(string, 1))

拡張:

def replace_n(string, n, first=0):
    letters = (
        # i % n == 0 means this letter should be replaced
        "*" if i % n == 0 else char

        # iterate index/value pairs
        for i, char in enumerate(string, -first)
    )
    return ''.join(letters)
>>> replace_n("hello world", 4)
'*ell* wo*ld'
>>> replace_n("hello world", 4, first=-1)
'hel*o w*orl*'
于 2012-12-02T11:31:52.110 に答える
2

あなたのコードにはいくつかの問題があります:

まず、return間違った場所にあります。for ループの内側にありますが、外側にある必要があります。次に、次のフラグメントで:

for i in range(len(str)):
    n=str[i]
    newStr=str.replace(n, "*")

関数のn2 番目の引数として渡した は、ループ ステップごとに上書きされます。したがって、最初の文字列が「abcabcabcd」で、n=3 (数値) を 2 番目の引数として渡す場合、ループの動作は次のようになります。

n="a"
n="b"
n="c"
...

したがって、値 3 は使用されません。さらに、ループでは、文字列で行われた最後の置換のみが保存されます。

n="a"
newStr="abcabcabcd".replace("a", "*") --> newStr = "*bc*bc*bcd"
n="b"
newStr="abcabcabcd".replace("b", "*") --> newStr = "a*ca*ca*cd"
...
n="d"
newStr="abcabcabcd".replace("d", "*") --> newStr = "abcabcabc*"

関数を(return位置を修正した後に)いくつかの文字列でテストすると、うまくいくようです:

In [7]: replaceN("abcabcabc", 3)
Out[7]: 'ab*ab*ab*'

ただし、より慎重に選択すると、次のようになります。

In [10]: replaceN("abcabcabcd", 3)
Out[10]: 'abcabcabc*'

次に、コードが失敗することは明らかであり、文字列の最後の文字のみを置き換えることと同等です。

my_string.replace(my_string[-1], "*")

エリックによって与えられたコードは正常に動作しています:

In [16]: ''.join("*" if i % 3 == 0 else char for i, char in enumerate("abcabcabcd"))
Out[16]: '*bc*bc*bc*'

3 番目、6 番目、9 番目などの位置を置き換えます。位置 0 も置き換えたくない場合は、調整が必要になる場合があります。

于 2012-12-02T12:06:47.523 に答える
0

reを使用する別のオプション:

import re
def repl(matchobj):
    return re.sub('.$','*',matchobj.group(0))
def replaceN(str, n):
    return re.sub('.'*n,repl,str)

ただし、これには追加のライブラリが必要です。このライブラリが既にインポートされている場合、これは簡単な方法である可能性があります。

于 2012-12-02T11:45:06.343 に答える
0

毎回文字列を再定義する簡単な方法:

def replaceN(string, n):
    for i in range(n, len(string), n):
        string = string[:i-1] + "*" + string[i:]
    return string


In [1]: replaceN("abcabcabc", 3)
Out[1]: ab*ab*ab*
In [2]: replaceN("abcd abcd abcd", 4)
Out[2]: abcd*abcd*abcd
于 2012-12-02T12:17:29.553 に答える
0

ループ内に return を配置したため、最初の反復の後、残りの文字列が置き換えられずに文字列が返されます。ループが完全に終了したら、文字列を返す必要があります。このようなものが動作するはずです:

def replaceN(str, n):
    for i in range(len(str)):
        n=str[i]
        newStr=str.replace(n, "*")
    return newStr
于 2012-12-02T11:29:11.803 に答える
0

エリックの答えは気に入っていますが、コメントで最初の文字を置き換えてはならないことを示しました。次のようにコードを適応させることができます。

''.join("*" if i % n == 0 else char for i, char in enumerate(string, 1))
                                             the difference is here  ^

def replaceN(s, n):
    return ''.join(
      '*' if not i%n else char for i, char in enumerate(s, 1))

>>> replaceN('welcome', 3)
'we*co*e'
于 2012-12-02T12:07:21.417 に答える