4

文字列に「(TOKEN)」という10個の異なるトークンがあるとします。ランダムに選択された2つのトークンを他の文字列に置き換えて、他のトークンをそのまま残すにはどうすればよいですか?

4

7 に答える 7

2
>>> import random
>>> text = '(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)'
>>> token = '(TOKEN)'
>>> replace = 'foo'
>>> num_replacements = 2
>>> num_tokens = text.count(token) #10 in this case
>>> points = [0] + sorted(random.sample(range(1,num_tokens+1),num_replacements)) + [num_tokens+1]
>>> replace.join(token.join(text.split(token)[i:j]) for i,j in zip(points,points[1:]))
'(TOKEN)__(TOKEN)__(TOKEN)__(TOKEN)__foo__(TOKEN)__foo__(TOKEN)__(TOKEN)__(TOKEN)'

関数形式:

>>> def random_replace(text, token, replace, num_replacements):
        num_tokens = text.count(token)
        points = [0] + sorted(random.sample(range(1,num_tokens+1),num_replacements)) + [num_tokens+1]
        return replace.join(token.join(text.split(token)[i:j]) for i,j in zip(points,points[1:]))

>>> random_replace('....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....','(TOKEN)','FOO',2)
'....FOO....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....(TOKEN)....FOO....'

テスト:

>>> for i in range(0,9):
        print random_replace('....(0)....(0)....(0)....(0)....(0)....(0)....(0)....(0)....','(0)','(%d)'%i,i)


....(0)....(0)....(0)....(0)....(0)....(0)....(0)....(0)....
....(0)....(0)....(0)....(0)....(1)....(0)....(0)....(0)....
....(0)....(0)....(0)....(0)....(0)....(2)....(2)....(0)....
....(3)....(0)....(0)....(3)....(0)....(3)....(0)....(0)....
....(4)....(4)....(0)....(0)....(4)....(4)....(0)....(0)....
....(0)....(5)....(5)....(5)....(5)....(0)....(0)....(5)....
....(6)....(6)....(6)....(0)....(6)....(0)....(6)....(6)....
....(7)....(7)....(7)....(7)....(7)....(7)....(0)....(7)....
....(8)....(8)....(8)....(8)....(8)....(8)....(8)....(8)....
于 2012-04-08T05:52:01.150 に答える
1

正確に2つ必要な場合は、次のようにします。

  1. トークンを検出します(文字列へのインデックスなど、トークンへのリンクをいくつか保持します)
  2. ランダムに2つ選択してください(random.choice
  3. それらを交換してください
于 2012-04-08T03:31:45.053 に答える
1

コードでの私の解決策:

import random

s = "(TOKEN)test(TOKEN)fgsfds(TOKEN)qwerty(TOKEN)42(TOKEN)(TOKEN)ttt"
replace_from = "(TOKEN)"
replace_to = "[REPLACED]"
amount_to_replace = 2

def random_replace(s, replace_from, replace_to, amount_to_replace):
    parts = s.split(replace_from)
    indices = random.sample(xrange(len(parts) - 1), amount_to_replace)

    replaced_s_parts = list()

    for i in xrange(len(parts)):
        replaced_s_parts.append(parts[i])
        if i < len(parts) - 1:
            if i in indices:
                replaced_s_parts.append(replace_to)
            else:
                replaced_s_parts.append(replace_from)

    return "".join(replaced_s_parts)

#TEST

for i in xrange(5):
    print random_replace(s, replace_from, replace_to, 2)

説明:

  1. を使用して文字列をいくつかの部分に分割しますreplace_from
  2. を使用して置き換えるトークンのインデックスを選択しrandom.sampleます。この返されたリストには一意の番号が含まれています
  3. 文字列を再構築するためのリストを作成し、トークンを によって生成されたインデックスに置き換えますreplace_to
  4. すべてのリスト要素を単一の文字列に連結する
于 2012-04-08T03:47:59.370 に答える
1

正確に何をしようとしているのですか?良い答えはそれに依存します...

そうは言っても、頭に浮かぶ力ずくの解決策は次のとおりです。

  1. tokens[0] が最初のトークン、tokens[1] が 2 番目のトークン、というように、10 個のトークンを配列に格納します。
  2. 辞書を作成して、一意の「(TOKEN)」を次の 2 つの数字に関連付けます: start_idx、end_idx
  3. 文字列を調べて 10 個のトークンのそれぞれを探す小さなパーサーを作成します。見つかったら、そのトークンが発生する文字列に開始/終了インデックスを (start_idx、end_idx として) 記録します。
  4. 解析が完了したら、[0,9] の範囲で乱数を生成します。これをRとしましょう
  5. これで、ランダムな "(TOKEN)" は tokens[ R ];
  6. 手順 (3) で辞書を使用して、文字列内の start_idx、end_idx の値を見つけます。そこのテキストを「他の文字列」に置き換えます
于 2012-04-08T03:35:44.777 に答える
1

この解決策を試してください:

import random

def replace_random(tokens, eqv, n):
    random_tokens = eqv.keys()
    random.shuffle(random_tokens)
    for i in xrange(n):
        t = random_tokens[i]
        tokens = tokens.replace(t, eqv[t])
    return tokens

トークンを含む文字列が存在し、各トークンを置換して適切な等価テーブルを構築できると仮定します。

tokens = '(TOKEN1) (TOKEN2) (TOKEN3) (TOKEN4) (TOKEN5) (TOKEN6) (TOKEN7) (TOKEN8) (TOKEN9) (TOKEN10)'

equivalences = {
    '(TOKEN1)' : 'REPLACEMENT1',
    '(TOKEN2)' : 'REPLACEMENT2',
    '(TOKEN3)' : 'REPLACEMENT3',
    '(TOKEN4)' : 'REPLACEMENT4',
    '(TOKEN5)' : 'REPLACEMENT5',
    '(TOKEN6)' : 'REPLACEMENT6',
    '(TOKEN7)' : 'REPLACEMENT7',
    '(TOKEN8)' : 'REPLACEMENT8',
    '(TOKEN9)' : 'REPLACEMENT9',
    '(TOKEN10)' : 'REPLACEMENT10'
}

次のように呼び出すことができます。

replace_random(tokens, equivalences, 2)
> '(TOKEN1) REPLACEMENT2 (TOKEN3) (TOKEN4) (TOKEN5) (TOKEN6) (TOKEN7) (TOKEN8) REPLACEMENT9 (TOKEN10)'
于 2012-04-08T04:04:11.093 に答える
1

これを行う方法はたくさんあります。私のアプローチは、元の文字列、トークン文字列、および元のトークンの出現に対する置換テキストを返す関数を受け取る関数を作成することです。

def strByReplacingTokensUsingFunction(original, token, function):
    outputComponents = []
    matchNumber = 0
    unexaminedOffset = 0
    while True:
        matchOffset = original.find(token, unexaminedOffset)
        if matchOffset < 0:
            matchOffset = len(original)
        outputComponents.append(original[unexaminedOffset:matchOffset])
        if matchOffset == len(original):
            break
        unexaminedOffset = matchOffset + len(token)
        replacement = function(original=original, offset=matchOffset, matchNumber=matchNumber, token=token)
        outputComponents.append(replacement)
        matchNumber += 1
    return ''.join(outputComponents)

(これを変更して、より短い識別子を使用することもできます。私のスタイルは、典型的な Python スタイルよりもやや冗長です。)

その関数を考えると、10 のうち 2 つのランダムな出現を簡単に置き換えることができます。入力例を次に示します。

sampleInput = 'a(TOKEN)b(TOKEN)c(TOKEN)d(TOKEN)e(TOKEN)f(TOKEN)g(TOKEN)h(TOKEN)i(TOKEN)j(TOKEN)k'

random モジュールには、母集団からランダムに項目を選択する (同じ項目を 2 回選択するのではなく) 便利な方法があります。

import random
replacementIndexes = random.sample(range(10), 2)

次に、上記の関数を使用して、ランダムに選択されたオカレンスを置き換えることができます。

sampleOutput = strByReplacingTokensUsingFunction(sampleInput, '(TOKEN)',
    (lambda matchNumber, token, **keywords:
        'REPLACEMENT' if (matchNumber in replacementIndexes) else token))
print sampleOutput

そして、ここにいくつかのテスト出力があります:

a(TOKEN)b(TOKEN)cREPLACEMENTd(TOKEN)e(TOKEN)fREPLACEMENTg(TOKEN)h(TOKEN)i(TOKEN)j(TOKEN)k

別の実行を次に示します。

a(TOKEN)bREPLACEMENTc(TOKEN)d(TOKEN)e(TOKEN)f(TOKEN)gREPLACEMENTh(TOKEN)i(TOKEN)j(TOKEN)k
于 2012-04-08T04:20:04.520 に答える
0
from random import sample

mystr = 'adad(TOKEN)hgfh(TOKEN)hjgjh(TOKEN)kjhk(TOKEN)jkhjk(TOKEN)utuy(TOKEN)tyuu(TOKEN)tyuy(TOKEN)tyuy(TOKEN)tyuy(TOKEN)'

def replace(mystr, substr, n_repl, replacement='XXXXXXX', tokens=10, index=0):
    choices = sorted(sample(xrange(tokens),n_repl))
    for i in xrange(choices[-1]+1):
        index = mystr.index(substr, index) + 1
        if i in choices:
            mystr = mystr[:index-1] + mystr[index-1:].replace(substr,replacement,1)
    return mystr

print replace(mystr,'(TOKEN)',2)
于 2012-04-08T05:57:50.753 に答える