2 votes

Comportement des itérateurs Python

Étant donné une chaîne de caractères arbitraire, je suis censé trouver la somme de tous les chiffres de cette chaîne. Cela nécessite évidemment que je connaisse le PROCHAIN élément de la chaîne tout en l'itérant... et que je décide si c'est un entier. Si l'élément précédent était aussi un entier, les deux éléments forment un nouvel entier, tous les autres caractères sont ignorés et ainsi de suite.

Par exemple, une chaîne d'entrée

ab123r.t5689yhu8 

devrait aboutir à la somme de 123 + 5689 + 8 = 5820 .

Tout cela doit être fait sans utiliser d'expressions régulières.

J'ai implémenté un itérateur en python, dont la méthode (next()) renvoie l'élément suivant, mais en passant la chaîne de caractères d'entrée.

acdre2345ty 

J'obtiens le résultat suivant

a
c
d
r
e
2
4
t
y

Certains chiffres 3 et 5 sont manquants... pourquoi ? J'ai besoin que le next() pour que je puisse passer en revue une chaîne d'entrée et effectuer les calculs correctement.

Mieux encore, comment dois-je implémenter la méthode next pour qu'elle donne l'élément situé immédiatement à droite lors d'une itération donnée ?

Voici mon code

class Inputiterator(object):
    '''
    a simple iterator to yield all elements from a given
    string successively from  a given input string
    '''
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def next(self):
        """
        check whether we've reached the end of the input
        string, if not continue returning the current value
        """
        if self.index == len(self.data)-1:
            raise StopIteration
        self.index = self.index + 1
        return self.data[self.index]

# Create a method to get the input from the user
# simply return a string

def get_input_as_string():
    input=raw_input("Please enter an arbitrary string of numbers")
    return input

def sort_by_type():
    maininput= Inputiterator(get_input_as_string())
    list=[]
    s=""
    for char in maininput:
        if str(char).isalpha():
            print ""+ str(char)
        elif str(char).isdigit() and str(maininput.next()).isdigit():
            print ""+ str(char)

sort_by_type()

9voto

GaretJax Points 3345

Les chaînes Python sont déjà itérables, pas besoin de créer votre propre itérateur.

Ce que vous voulez est donc simplement réalisé sans itérateurs :

s = "acdre2345ty2390"

total = 0
num = 0

for c in s:
    if c.isdigit():
        num = num * 10 + int(c)
    else:
        total += num
        num = 0

total += num

Ce qui a pour conséquence :

>>> print total
4735

3voto

Rik Poggi Points 10195

Cela peut être fait avec itertools.groupby :

from itertools import groupby

s = 'ab123r#t5689yhu8'
tot = 0
for k, g in groupby(s, str.isdigit):
    if k:
        tot += int(''.join(g))

Ou en une ligne (comme suggéré dans les commentaires ci-dessous) :

tot = sum((int(''.join(g)) for k, g in groupby(s, str.isdigit) if k)

2voto

joaquin Points 22450

Edit : J'ai d'abord supprimé cette réponse car il y a des solutions bien meilleures pour votre problème dans ce fil, mais comme vous demandez directement comment utiliser la méthode suivante pour faire fonctionner votre code, je l'ai récupérée, au cas où vous la trouveriez utile.

Essayez ceci (j'ai simulé l'itérateur pour plus de commodité) :

def sort_by_type():
    maininput = iter("acdre2345ty")

    for char in maininput:
        if char.isalpha():
            print char
        elif char.isdigit():
            number = char
            while True:
                # try/except could take care of the StopIteration exception 
                # when a digit is last in the string
                #
                # try:
                #    char = maininput.next()
                # except StopIteration:
                #    char = ""
                #
                # however using next(iterator, default) is much better:
                #
                char = next(maininput, "")

                if char.isdigit():
                    number += char
                else:
                    break
            print number
            print char

si produit :

a
c
d
r
e
2345
t
y

1voto

GuillaumeDufay Points 317

À des fins de divertissement uniquement (je n'ai pas pu résister, 49 caractères) :

eval(''.join([['+0+',x][x.isdigit()]for x in s]))

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