Поведение итератора Python - PullRequest
2 голосов
/ 28 января 2012

Учитывая произвольную входную строку, я должен найти сумму всех чисел в этой строке. Это, очевидно, требует, чтобы я знал следующий элемент в строке при переборе его ... и принял решение, является ли оно целым числом. если предыдущий элемент также был целым числом, два элемента образуют новое целое число, все остальные символы игнорируются и т. д.

Например, входная строка

ab123r.t5689yhu8 

должно привести к сумме 123 + 5689 + 8 = 5820.

Все это должно быть сделано без использования регулярных выражений.

Я реализовал итератор в python, метод которого (next ()), я думаю, возвращает следующий элемент, но пропуская входную строку

acdre2345ty 

Я получаю следующий вывод

a
c
d
r
e
2
4
t
y

Некоторые номера 3 и 5 отсутствуют ... почему это? Мне нужно, чтобы next() работал, чтобы я мог просеивать входную строку и правильно выполнять вычисления

Еще лучше, как я должен реализовать следующий метод, чтобы он возвращал элемент непосредственно в течение данной итерации?

Вот мой код

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()

Ответы [ 4 ]

9 голосов
/ 28 января 2012

Строки Python уже итерируемы, нет необходимости создавать свой собственный итератор.

Таким образом, то, что вы хотите, просто достигается без итераторов:

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

В результате:

>>> print total
4735
3 голосов
/ 28 января 2012

Это можно сделать с помощью 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))

или одной строкой (как указано в комментариях ниже) :

tot = sum((int(''.join(g)) for k, g in groupby(s, str.isdigit) if k)
2 голосов
/ 28 января 2012

Редактировать: Я сначала удалил этот ответ, так как в этой теме есть гораздо лучшие решения для вашей проблемы, но, поскольку вы прямо спрашиваете, как использовать следующий метод, чтобы ваш код работал, я восстановил его на случай, если вы найдете это полезным.

Попробуйте это (для удобства я издевался над итератором):

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

если выдает:

a
c
d
r
e
2345
t
y
1 голос
/ 28 января 2012

Только для развлекательных целей (я не удержался, 49 символов):

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