user5673516
user5673516

Reputation:

Python: AttributeError: 'NoneType' object has no attribute 'groups'

I am using regex to calculate the value of a string that contains real numbers and addition, such as '3.4+5.2'. This is the code:

import re

a = str(raw_input())

counter = a.count('+')
for i in range(counter):
    add = re.match('([\+\-]?\d+(?:\.\d+)?)\+([\+\-]?\d+(?:\.\d+)?)', a)
    temp = float(add.groups()[0]) + float(add.groups()[1])
    a = re.sub('([\+\-]?\d+(?:\.\d+)?)\+([\+\-]?\d+(?:\.\d+)?)', str(temp), a)
print a

It works fine for:

>>> a = '3+4'
'7.0'
>>> a = '3+4+5'
'12.0'

But, when I try to add more than twice:

>>> a = '3+4+5+6'
7.07.0
    temp = float(add.groups()[0]) + float(add.groups()[1])
AttributeError: 'NoneType' object has no attribute 'groups'

Why does this error appear, how can it be fixed?

Upvotes: 1

Views: 2111

Answers (1)

falsetru
falsetru

Reputation: 369054

re.match() returns None if there's no match. Trying to access groups raises AttributeError. (None.groups(...))

After the first iteration, a become 7.07.0 which does not have +. The reason is re.sub replace all matches, not only the first match.

To make it replace only the first occurence, you need to specify count:

a = re.sub('([\+\-]?\d+(?:\.\d+)?)\+([\+\-]?\d+(?:\.\d+)?)', str(temp), a, count=1)

As Kevin Guan commented, using str.split() will be better; easy to read, simple:

>>> '3+4+5+6'.split('+')
['3', '4', '5', '6']
>>> map(float, '3+4+5+6'.split('+'))
[3.0, 4.0, 5.0, 6.0]
>>> sum(map(float, '3+4+5+6'.split('+')))
18.0

Upvotes: 1

Related Questions