web-dev-qa-db-ja.com

文字列内の文字をランダムに大文字にする

文字列の各文字をランダムに大文字または小文字にしたい。私はPythonで文字列を扱うのは初めてですが、文字列は不変であるため、次のことはできません。

i =0             
for c in sentence:
    case = random.randint(0,1)
    print("case = ", case)
    if case == 0:
        print("here0")
        sentence[i] = sentence[i].lower()
    else:
        print("here1")
        sentence[i] = sentence[i].upper()
    i += 1
print ("new sentence = ", sentence)

そして、エラーを取得します:TypeError: 'str'オブジェクトはアイテムの割り当てをサポートしていません

しかし、他にどのようにこれを行うことができますか?

14
user1045890

次のようなジェネレータ式でstr.joinを使用できます。

from random import choice
sentence = 'Hello World'
print(''.join(choice((str.upper, str.lower))(c) for c in sentence))

出力例:

heLlo WORLd
21
blhsing

新しい文字列を作成します。

元のコードに少し変更を加えた解決策は次のとおりです。

>>> import random
>>> 
>>> def randomcase(s):
...:    result = ''
...:    for c in s:
...:        case = random.randint(0, 1)
...:        if case == 0:
...:            result += c.upper()
...:        else:
...:            result += c.lower()
...:    return result
...:
...:
>>> randomcase('Hello Stackoverflow!')
>>> 'hElLo StaCkoVERFLow!'

編集:私はblhsingの方がいいので私のワンライナーを削除しました。

6
timgeb

文字列の実装をリストの実装に変更するだけです。文字列は不変なので、オブジェクト内の値を変更することはできません。しかし、Listsは可能性があるので、コードのその部分のみを変更しました。そして、これを行うにはもっと良い方法があることに注意してください、フォロー ここ

import random
sentence = "This is a test sentence" # Strings are immutable
i =0
new_sentence = [] # Lists are mutable sequences
for c in sentence:
    case = random.randint(0,1)
    print("case = ", case)
    if case == 0:
        print("here0")
        new_sentence += sentence[i].lower() # append to the list
    else:
        print("here1")
        new_sentence += sentence[i].upper() # append to the list
    i += 1
print ("new sentence = ", new_sentence)

# to print as string
new_sent = ''.join(new_sentence)
print(new_sent)
3
Vineeth Sai
sentence='quick test' 
print(''.join([char.lower() if random.randint(0,1) else char.upper() for char in sentence]))

qUiCK TEsT
3
Venkatachalam

あなたは以下のようにすることができます

char_list = []            
for c in sentence:
    ucase = random.randint(0,1)
    print("case = ", case)
    if ucase:
        print("here1")
        char_list.append(c.upper())
    else:
        print("here0")
        char_list.append(c.lower())
print ("new sentence = ", ''.join(char_list))
2
ansu5555

pythonループを含まない1つの方法は、それをnumpyに送信し、それに対してベクトル化された演算を実行することです。次に例を示します。

_import numpy as np
def randomCapitalize(s):
    s  = np.array(s, 'c').view('u1')
    t  = np.random.randint(0, 2, len(s), 'u1') # Temporary array
    t *= s != 32 # ASCII 32 (i.e. space) should not be lowercased
    t *= 32 # Decrease ASCII by 32 to lowercase
    s -= t
    return s.view('S' + str(len(s)))[0]
randomCapitalize('hello world jfwojeo jaiofjowejfefjawivj a jofjawoefj')
_

出力:

_b'HELLO WoRlD jFwoJEO JAioFjOWeJfEfJAWIvJ A JofjaWOefj'
_

このソリューションは、特に長い文字列の場合、かなり高速でなければなりません。この方法には2つの制限があります。

  • 入力は完全に小文字でなければなりません。最初に.lower()を試すことができますが、技術的には効率が低くなります。

  • 非a-to-z文字には特別な注意が必要です。上記の例では、スペースのみが処理されます

置換することで、より多くの特殊文字を同時に処理できます

_t *= s != 32
_

_# using space, enter, comma, period as example
t *= np.isin(s, list(map(ord, ' \n,.')), invert=True)
_

例えば:

_s = 'ascii table and description. ascii stands for american standard code for information interchange. computers can only understand numbers, so an ascii code is the numerical representation of a character such as'
randomCapitalize(s)
_

出力:

_b'ascII tABLe AnD descRiptIOn. ascii sTaNds for AmEricAN stanDaRD codE FOr InForMAtION iNTeRCHaNge. ComPUtERS can onLY UNdersTand nUMBers, So An asCIi COdE IS tHE nuMERIcaL rEPrEsEnTATion Of a CHaractEr such as'
_
0
ZisIsNotZis