Home > front end >  Coverting Str into Int and Float, respectively
Coverting Str into Int and Float, respectively

Time:03-11

Im a beginner in python so forgive me if the answer is comical :)

I'm trying to write some code that coverts str into int and floats. I will give an example below:

if we are given this:

data = [['ab2'], ['-123'], ['BIKES', '3.2'], ['3.0', ' 4', '-5.0']]

we need to return this:

data = [['ab2'], [-123], ['BIKES', 3.2], [3, 4, -5]]

I have tried in several ways to do this like so:

# first attempt
for sublist in data:
        for value in range(0, len(sublist)): 
            if "." in sublist[value]:
                sublist[value] = float(sublist[value])
            elif sublist[value].isnumeric():
                sublist[value] = int(sublist[value])
# second attempt
for sublist in data:
    for value in sublist:
        if value.isnumeric():
            if int(value) == float(value):
                value = int(value)
            else:
                value = float(value)

I keep coming back to the same few problems though:

  1. the isnumeric or isdigit doesn't accept "-", " " or "." in the answer, so if i have "-123.4" thats not a number
  2. Numbers like 3.0 or 4.0, need to be converted into integers and not floats
  3. I need a way to mutate the original list and basically "replace' the old numbers, with new

I know you can use try/except blocks but i haven't studied those and I don't understand them, so if anyone could give me some guidance on what to do, or how to alter my code, it would be greatly appreciated :)

Thanks

CodePudding user response:

This uses a regex to find valid numbers. Like most such filters, this creates a new list with the desired values instead of writing in place.

import re

nums = r"[ -]?[\d.] "

data = [['ab2'], ['-123'], ['BIKES', '3.2'], ['3.0', ' 4', '-5.0']]

newlist = []
for sublist in data:
    newsub = []
    for value in sublist:
        if re.match( nums, value ):
            if '.' not in value:
                newsub.append( int(value) )
            else:
                value = value.rstrip('0').rstrip('.')
                if '.' not in value:
                    newsub.append( int(value) )
                else:
                    newsub.append( float(value) )
        else:
            newsub.append( value )
    newlist.append( newsub )

print(newlist)

CodePudding user response:

Using a nested try/except:

def to_num(s):
    # remove trailing ".0"
    x = s.rstrip('0').rstrip('.') if '.' in s else s
    try: # attempt int conversion
        return int(x)
    except ValueError:
        try: # attempt float conversion
            return float(x)
        except ValueError:
            return s   # if all failed return input

[[to_num(x) for x in l] for l in data]

Output:

[['ab2'], [-123], ['BIKES', 3.2], [3, 4, -5]]

CodePudding user response:

The easiest solution is to use a try-except block. After all, it's easier to ask forgiveness than permission. With a try-except, as soon as an error is encountered in the try block, control moves to the except block.

In the example below, if float(value) fails, a ValueError is raised. This error means the except ValueError: block will be executed. Since we just want to ignore the error, we pass in the except block.

If no error is raised, execution continues on to the next statement (if float_value...) and the except block is skipped.

for sublist in data:
    for index in range(len(sublist)): 
        value = sublist[index]
        
        try:
            float_value = float(value)             # Convert to float
            if float_value.is_integer():           # If successful, check if it's an integer
                sublist[index] = int(float_value)  # If integer, convert to integer and save the integer value
            else:
                sublist[index] = float_value       # If not, save the float
            continue                               # Skip the rest of the loop
        except ValueError:                         # Catch ValueError if float() fails
            pass                                   # Do nothing if error
         

Which gives:

data = [['ab2'], [-123], ['BIKES', 3.2], [3, 4, -5]]

CodePudding user response:

# Assuming data only contains list and in the list elements can also be list

data = [['ab2'], ['-123'], ['BIKES', '3.2'], ['3.0', ' 4', '-5.0']]


def checkPureInt(n):
    n_str = str(n)
    if n_str[-1] == '0' and n_str[-2] == ".":
        return True
    else:
        return False


for i in range(len(data)):
    if type(data[i]) == list:

        for j in range(len(data[i])):
            try:
                data[i][j] = float(data[i][j])
                if checkPureInt(data[i][j]):
                    data[i][j] = int(data[i][j])
            except:
                pass

print(data)

CodePudding user response:


import math
def is_number(string):
    try:
        float(string)
        return True
    except ValueError:
        return False
data=[['ab2'], ['-123'], ['BIKES', '3.2'], ['3.0', ' 4', '-5.0']]
for i in range(len(data)):
    for j in range(len(data[i])):
        value=data[i][j]
        if is_number(value):
            if int(float(value)) == float(value):
                data[i][j] = int(float(value))
                #print(value)
            else:
                data[i][j] = float(value)
                #print(value)
print(data)
  • Related