0

I aim to print a list of every element inside a user-inputted list. The outputted list identifies symbols as strings, and numbers as floats, to basically compare elements as floats and strings. If the number in the list is already a float, the output is not printed properly.

expression_list = []
expression = "(3.1+2)*5"

for index in expression:
    try: 
        float_index = float(index)
        expression_list.append(float_index)
    except ValueError:
        expression_list.append(index)
print(expression_list)     

I expect the output to be ['(', 3.1, '+', 2.0, ')', '*', 5.0] instead I get ['(', 3.0, '.', 1.0, '+', 2.0, ')', '*', 5.0]

3
  • 2
    I voted to reopen, because the duplicate link, which concerns floats in Python, seems to have nothing to do with the OP, which is about parsing an arithmetic expression into logical components. Commented May 13, 2019 at 5:24
  • @tripleee Yes, I too do not believe the marked duplicate answers the question. Commented May 13, 2019 at 5:28
  • Thanks for the ping and sorry for the wrong duplicate. I'll see if I can find a better one. Commented May 13, 2019 at 5:45

2 Answers 2

2

I would use re.findall here:

expression = "(3.1+2)*5"
output = re.findall(r'[()]|[^\w]+|(?:\d+(?:\.\d+)?)', expression)
print(output)

['(', '3.1', '+', '2', ')', '*', '5']

The pattern used is:

[()] | [^\w]+ | (?:\d+(?:\.\d+)?)

This matches:

[()]              an opening or closing parenthesis, as a separate match
[^\w]             any other non word character
(?:\d+(?:\.\d+)?  a number, with or without a decimal component
Sign up to request clarification or add additional context in comments.

3 Comments

Hi @TimBiegeleisen, I referred to your answer in mine, and then used the code to come up with the final solution for the OP, is that fine?
@DeveshKumarSingh You cited me, I have no problem with this :-) ... in case you can't tell, I don't know much Python, outside of the regex and SQL APIs.
Thanks @TimBiegeleisen, In that case, can I get an upvote lol :)
1

This is happening because your for loop for index in expression: iterates through every character of the string, so it is not checking if 3.1 is a float, it checks if 3 is a float and 1 is a float by converting it, and float('3')=3.0, hence you see the result.

In [8]: expression_list = [] 
   ...: expression = "(3.1+2)*5" 
   ...:  
   ...:  
   ...: for index in expression: 
   ...:     print(index) 
   ...:                                                                                                                                                                           
(
3
.
1
+
2
)
*
5

Perhaps you can split the strings in a manner which extract out the floats and the operators and brackets, which Tim's answer has provided to you.

Assuming you have that output, your code will work as expected

import re

expression_list = []
expression = "(3.1+2)*5"

literals = re.findall(r'[()]|[^\w]+|(?:\d+(?:\.\d+)?)', expression)

for index in literals:
    try:
        float_index = float(index)
        expression_list.append(float_index)
    except ValueError:
        expression_list.append(index)
print(expression_list)

The output will be ['(', 3.1, '+', 2.0, ')', '*', 5.0] as you expected!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.