0 votes

Solutions de contournement lorsqu'une chaîne est trop longue pour un .join. OverflowError se produit

Je travaille sur des problèmes de python sur pythonchallenge.com pour m'enseigner le python et j'ai rencontré un obstacle, puisque la chaîne que je dois utiliser est trop grande pour que python la gère. Je reçois cette erreur :

my-macbook:python owner1$ python singleoccurrence.py
Traceback (most recent call last):
  File "singleoccurrence.py", line 32, in <module>
    myString = myString.join(line)
OverflowError: join() result is too long for a Python string

Quelles sont les alternatives dont je dispose pour ce problème ? Mon code ressemble à ceci...

#open file testdata.txt
#for each character, check if already exists in array of checked characters
#if so, skip.
#if not, character.count
#if count > 1, repeat recursively with first character stripped off of page.
# if count = 1, add to valid character array.
#when string = 0, print valid character array.

valid = []
checked = []
myString = ""

def recursiveCount(bigString):
    if len(bigString) == 0:
        print "YAY!"
        return valid
    myChar = bigString[0]
    if myChar in checked:
        return recursiveCount(bigString[1:])
    if bigString.count(myChar) > 1:
        checked.append(myChar)
        return recursiveCount(bigString[1:])
    checked.append(myChar)
    valid.append(myChar)
    return recursiveCount(bigString[1:])

fileIN = open("testdata.txt", "r")
line = fileIN.readline()

while line:
    line = line.strip()
    myString = myString.join(line)
    line = fileIN.readline()

myString = recursiveCount(myString)
print "\n"
print myString

10voto

Nelson Points 3878

string.join ne fait pas ce que vous pensez. join est utilisé pour combiner une liste de mots en une seule chaîne avec le séparateur donné. Par exemple :

>>> ",".join(('foo', 'bar', 'baz'))
'foo,bar,baz'

Le bout de code que vous avez posté tentera d'insérer maChaîne entre chaque caractère de la ligne de la variable. Vous pouvez imaginer que cela va vite devenir énorme :-). Essayez-vous de lire l'intégralité du fichier dans une seule chaîne, maChaîne ? Si c'est le cas, la façon dont vous voulez concaténer les chaînes de caractères est la suivante :

myString = myString + line

Pendant que j'y suis... puisque vous apprenez le Python, voici quelques autres suggestions.

Il existe des moyens plus simples de lire un fichier entier dans une variable. Par exemple :

fileIN = open("testdata.txt", "r")
myString = fileIN.read()

(Cela n'aura pas le comportement exact de votre code strip() existant, mais peut en fait faire ce que vous voulez).

De plus, je ne recommanderais jamais à un code Python pratique d'utiliser la récursion pour itérer sur une chaîne de caractères. Votre code fera un appel de fonction (et une entrée dans la pile) pour chaque caractère de la chaîne. De plus, je ne suis pas sûr que Python soit très intelligent quant à toutes les utilisations de bigString[1 :]: il pourrait bien créer une deuxième chaîne en mémoire qui serait une copie de l'original sans le premier caractère. La manière la plus simple de traiter chaque caractère d'une chaîne est la suivante :

for mychar in bigString:
    ... do your stuff ...

Enfin, vous utilisez la liste nommée "check" pour savoir si vous avez déjà vu un caractère particulier auparavant. Mais le test d'appartenance aux listes ("if myChar in checked") est lent. En Python, il est préférable d'utiliser un dictionnaire :

checked = {}
...
if not checked.has_key(myChar):
    checked[myChar] = True
    ...

L'exercice que vous faites est un excellent moyen d'apprendre plusieurs idiomes Python.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X