Je veux majuscule ou majuscule au hasard ou en minuscule chaque lettre dans une chaîne. Je commence à travailler avec des chaînes en python, mais comme les chaînes sont immuables, je ne peux pas effectuer les opérations suivantes:
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)
Et obtenez l'erreur: TypeError: l'objet 'str' ne prend pas en charge l'affectation d'élément
Mais alors, comment pourrais-je faire cela autrement?
Vous pouvez utiliser str.join
avec une expression de générateur comme celle-ci:
from random import choice
sentence = 'Hello World'
print(''.join(choice((str.upper, str.lower))(c) for c in sentence))
Exemple de sortie:
heLlo WORLd
Construire une nouvelle chaîne.
Voici une solution avec de petites modifications à votre code d'origine:
>>> 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!'
edit: supprimé mes oneliners parce que j'aime mieux que blhsing.
Il suffit de changer l'implémentation de chaîne en implémentation de liste. Comme la chaîne est immuable, vous ne pouvez pas modifier la valeur à l'intérieur de l'objet. Mais Lists
peut être, j'ai donc seulement changé cette partie de votre code. Et notez qu'il existe de bien meilleures façons de le faire. Suivez ici
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)
sentence='quick test'
print(''.join([char.lower() if random.randint(0,1) else char.upper() for char in sentence]))
qUiCK TEsT
Vous pouvez faire comme ci-dessous
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))
Une façon de ne pas impliquer la boucle python serait de l'envoyer à numpy et d'effectuer l'opération vectorisée par dessus. Par exemple:
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')
qui produit:
b'HELLO WoRlD jFwoJEO JAioFjOWeJfEfJAWIvJ A JofjaWOefj'
Cette solution devrait être assez rapide surtout pour les longues chaînes. Il y a deux limitations de cette méthode:
L'entrée doit être entièrement en minuscule. Vous pouvez essayer .lower()
en premier lieu, mais son efficacité technique est faible.
Il a besoin d'attention particulière pour les caractères non-à-z. Dans l'exemple ci-dessus, seul l'espace est géré
Vous pouvez gérer beaucoup plus de caractères spéciaux en même temps en remplaçant
t *= s != 32
avec
# using space, enter, comma, period as example
t *= np.isin(s, list(map(ord, ' \n,.')), invert=True)
Par exemple:
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)
qui produit:
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'