Ce sont les listes que je veux gonfler:

https://i.stack.imgur.com/bX7Rn.png

C'est l'exemple d'exécution du programme que je veux faire:

https://i.stack.imgur.com/AYDOG.png

aList = [ "zero", "none", "nil", "null" ]
bList = [ "one", "won", "juan" ]
cList = [ "two", "to", "too", "tu" ]
dList = [ "three" ]
eList = [ "four", "for", "fore" ]
fList = [ "five" ]
gList = [ "six" ]
hList = [ "seven" ]
iList = [ "eight", "ate" ]
jList = [ "nine" ]
kList = [ "ten" ]
lList = [ "eleven" ]
mList = [ "twelve", "dozen" ]
nList = [ "never" ]
oList = [ "half" ]
pList = [ "once" ]
qList = [ "twice" ]
rList = [ "single" ]
sList = [ "double" ]
tList = [ "first" ]
uList = [ "second" ]
vList = [ "third" ]
wList = [ "fourth", "forth" ]


userInput = input( "Enter your sentence to inflate: " )
userInput = userInput.lower()


for i in userInput.split():
    if i in aList:
        userInput = userInput.replace( i, "one" )
    elif i in bList:
        userInput = userInput.replace( i, "two" )

Chaque fois que j'exécute ce code, cela fonctionne un peu, mais il entre en conflit avec d'autres listes, par exemple, voici l'exemple de mon code:

https://i.stack.imgur.com/xhDy4.png

Des idées sur la façon dont je peux faire fonctionner ce programme?

1
Jack 13 avril 2018 à 22:16

5 réponses

Meilleure réponse

Tout d'abord, n'utilisez pas de variable pour chaque mot. Utilisez une grande liste imbriquée, comme ceci:

replacements = [
    [["zero", "none", "nil", "null"], "one"],
    [["one", "won", "juan"], "two"],
    [["two", "to", "too", "tu"], "three"],
    [["three"], ""],
    [["four", "for", "fore"], ""],
    [["five"], ""],
    [["six"], ""],
    [["seven"], ""],
    [["eight", "ate"], ""],
    [["nine"], ""],
    [["ten"], ""],
    [["eleven"], ""],
    [["twelve", "dozen"], ""],
    [["never"], ""],
    [["half"], ""],
    [["once"], ""],
    [["twice"], ""],
    [["single"], ""],
    [["double"], ""],
    [["first"], ""],
    [["second"], ""],
    [["third"], ""],
    [["fourth", "forth"], ""],
]

(vous pouvez remplir le reste)

Ensuite, vous pouvez parcourir cette liste pour effectuer vos remplacements. Cela a été couvert dans d'autres réponses.

Pour résoudre votre problème, étant donné que one peut être remplacé par two et two peut être remplacé par three et ainsi de suite, cela signifie que vous devez remplacer tous {{X4} } s avant de remplacer two et de remplacer tous les two avant de remplacer one s ... vous devez donc parcourir la liste et effectuer les remplacements dans un ordre particulier. Je ne veux pas le donner complètement (même si je l'ai à peu près), prenez le temps d'y penser.

0
Alex Hall 13 avril 2018 à 19:37

Plutôt que de vérifier si chaque mot d'entrée se trouve dans l'une de vos listes, vous devez vérifier si l'un des mots de vos listes est dans l'entrée. par exemple.

for word in aList: 
    if word in userInput: 
        userInput.replace(word, 'one')
...

Et plutôt que d'avoir une tonne de listes avec beaucoup de copier-coller, vous pouvez structurer vos listes différemment pour pouvoir les parcourir. Peut-être quelque chose comme:

from collections import namedtuple
Replacement = namedtuple('Replacement', ['before', 'after'])
replacements = [
    Replacement(["zero", "none", "nil", "null"], "one"),        
    Replacement(["one", "won", "juan"],          "two"),
    ...
]
for replacement in replacements: 
    for word in replacement.before:
        userInput = userInput.replace(word, replacement.after)
0
0x5453 13 avril 2018 à 19:34

Je me suis beaucoup amusé avec ça. En utilisant re.sub, vous pouvez vraiment profiter de en utilisant le paramètre de fonction de sub pour accomplir cela. Ceci est super utile car chaque groupe capturé ne sera remplacé qu'une seule fois (en trouvant des motifs qui ne se chevauchent pas) donc pas de scans répétés de la même chaîne.

Cette solution n'est pas sujette à des problèmes de remplacement de numéros différents, mais uniquement l'ordre dans lequel vous placez vos mots dans la liste de sorte qu'un mot de la liste ne soit pas contenu dans un mot successif de la même liste . Assurez-vous donc que "à" vient après "aussi" sinon "outil" serait remplacé par "threeol" au lieu de " threel ".

from re import sub, IGNORECASE
subs = {    #The new words are the keys. Respective values are the old words to replace
    "one": [ "zero", "none", "nil", "null" ],
    "two": [ "one", "won", "juan" ],
    "three": [ "two", "too", "to", "tu" ],
    "four": [ "three" ],
    "five": [ "four", "for", "fore" ],
    "six": [ "five" ],
    "seven": [ "six" ],
    "eight": [ "seven" ],
    "nine": [ "eight", "ate" ],
    "ten": [ "nine" ],
    "eleven": [ "ten" ],
    "twelve": [ "eleven" ],
    "thirteen": [ "twelve", "dozen" ],
    "once": [ "never" ],
    "one and a half": [ "half" ],
    "twice": [ "once" ],
    "thrice": [ "twice" ],
    "double": [ "single" ],
    "triple": [ "double" ],
    "second": [ "first" ],
    "third": [ "second" ],
    "fourth": [ "third" ],
    "fifth": [ "fourth", "forth" ]
}

#Flatten list of substitutes into regular expression with named capture groups
all_replacements = '|'.join('(?P<{}>{})'.format(new.replace(' ', '_'), '|'.join(olds)) for new, olds in subs.items())

def inc(match):     #increment 1 from the match
    return str(int(match.group()) + 1)

def inflate(match): #Get the next named capture group that exists and send new
    return next(new for new, old in match.groupdict().items() if old)

def replace(string):
    string = sub(r'\d+', inc, string)  #Increment all numbers
    string = sub(all_replacements, inflate, string, flags=IGNORECASE) #Inflate all words
    return string

print(replace("I wonder"))
print(replace(""))
print(replace("It was the best of times."))
print(replace("A Tale of 2 Cities"))
print(replace("A WoNder if 18 is bigger than 1919191"))

Résultats dans les éléments imprimés suivants

I twoder

It was the best of times.
A Tale of 3 Cities
A twoder if 19 is bigger than 1919192

En fin de compte, votre liste peut être mise à l'échelle très facilement tout en conservant la lisibilité, car vous n'avez pas à modifier de code si vous décidez d'ajouter à votre liste de substitutions.

0
Sunny Patel 13 avril 2018 à 21:00

Vous devez remplacer:

for i in userInput.split():
    if i in aList:
        userInput = userInput.replace( i, "one" )
    elif i in bList:
        userInput = userInput.replace( i, "two" )

Avec juste:

for i in aList:
    userInput = userInput.replace( i, "one" )
for i in bList:
    userInput = userInput.replace( i, "two" )

Il passe simplement en revue chaque élément de chaque liste et le remplace.

0
Artemis still doesn't trust SE 13 avril 2018 à 19:29

Si vous structurez soigneusement vos données, vous pouvez supprimer deux boucles seulement:

lists = [
 { 
  "infl": "one", 
  "list": [ "zero", "none", "nil", "null" ] 
 },

 { "infl": "two",   "list": [ "one", "won", "juan" ] },
 { "infl": "three", "list": [ "two", "to", "too", "tu" ] },
 { "infl": "four",  "list": [ "three" ] },
 { "infl": "five",  "list": [ "four", "for", "fore" ] },
 # etc.... etc...
]

for lst in lists:
  for i in lst["list"]:
    userInput = userInput.replace(i, lst["infl"])
0
Kamil Jarosz 13 avril 2018 à 19:38