Thuita Wachira
Thuita Wachira

Reputation: 176

Python iterator behaviour

Given an arbitrary input string I'm meant to find the sum of all numbers in that string. This obviously requires that i know the NEXT element in string while iterating through it...and make the decision whether its an integer. if the previous element was an integer also, the two elements form a new integer, all other characters are ignored and so on.

For instance an input string

ab123r.t5689yhu8 

should result in the sum of 123 + 5689 + 8 = 5820.

All this is to be done without using regular expressions.

I have implemented an iterator in python, whose (next()) method i think returns the next element, but passing the input string

acdre2345ty 

I'm getting the following output

a
c
d
r
e
2
4
t
y

Some numbers 3 and 5 are missing...why is this? I need that the next() to work for me to be able to sift through an input string and do the calculations correctly

Better still, how should i implement the next method so that it yields the element to the immediate right during a given iteration?

Here is my 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()

Upvotes: 2

Views: 300

Answers (4)

GuillaumeDufay
GuillaumeDufay

Reputation: 1128

For entertainment purposes only (I couldn't resist, 49 chars):

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

Upvotes: 1

Rik Poggi
Rik Poggi

Reputation: 29312

This can be done with 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))

Or in one line (as suggested in the comments down below):

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

Upvotes: 3

joaquin
joaquin

Reputation: 85683

Edit: I first deleted this answer as there are much better solutions for your problem in this thread, but as you are directly asking how to use the next method to get your code working I have recovered it, in case you find it useful.

Try this (I mocked the iterator for convenience):

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

if produces:

a
c
d
r
e
2345
t
y

Upvotes: 2

GaretJax
GaretJax

Reputation: 7780

Python strings are already iterable, no need to create you own iterator.

What you want is thus simply achieved without iterators:

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

Which results in:

>>> print total
4735

Upvotes: 9

Related Questions