web-dev-qa-db-fra.com

Capitaliser au hasard des lettres dans une chaîne

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?

12
user1045890

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
21
blhsing

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.

6
timgeb

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)
4
Vineeth Sai
sentence='quick test' 
print(''.join([char.lower() if random.randint(0,1) else char.upper() for char in sentence]))

qUiCK TEsT
3
AI_Learning

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))
2
ansu5555

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'
0
ZisIsNotZis