directrex
directrex

Reputation: 3

How do I change the type of elements of a 2D list?

I have a list that I get by opening a txt file. That list is a 2D list which looks like:

[['25 1 100.5 2 300'], ['50 3 125.5 4 85']]

I want the sublists to not be strings but be integers (when the position is uneven in the list) and floats (when the position is even in the list). For instance, I want the list to look like:

[[25.0, 1, 100.5, 2, 300.0], [50.0, 3, 125.5, 4, 85.0]]

So far, I have tried

list = [['25 1 100.5 2 300'], ['50 3 125.5 4 85']]
for x in list:
    str_to_num = x.split()

And that's where I don't know how to separate which element will become a float and which will become an integer.

Upvotes: 0

Views: 848

Answers (3)

Andrew Allaire
Andrew Allaire

Reputation: 1350

Your problem is that your x.split() is trying to split a list rather than a string (note that ['25 1 100.5 2 300'] is a list with one element in it, which is the string '25 1 100.5 2 300'). If the sub lists are always going to have exactly one such string you could fix your code by using x[0].split() instead.

This is a combined corrected edit that presumes you want an int when you can get it or a float:

def to_number(num_str):
    try:
       return_value = int(num_str)
    except ValueError:
       return_value = float(num_str)
    return return_value

old_list = [['25 1 100.5 2 300'], ['50 3 125.5 4 85']]
new_list = []
for x in old_list:
   num_strs = x[0].split()
   new_list.append([to_number(_) for _ in num_strs])

Upvotes: 0

hpaulj
hpaulj

Reputation: 231665

Would you like a one-liner?

In [27]: ll = [['25 1 100.5 2 300'], ['50 3 125.5 4 85']]
In [28]: [[(int(x) if i%2 else float(x)) for i,x in 
               enumerate(l[0].split())] for l in ll]
Out[28]: [[25.0, 1, 100.5, 2, 300.0], [50.0, 3, 125.5, 4, 85.0]]

If you aren't picky about the int/float distinction, this will do:

In [32]: [[float(x) for x in l[0].split()] for l in ll]
Out[32]: [[25.0, 1.0, 100.5, 2.0, 300.0], [50.0, 3.0, 125.5, 4.0, 85.0]]

For many numeric operations it isn't important whether the value is float 1.0 or integer 1.

Another way to distinguish between int and floats is if int(astr) raises an error (int('1') v int('1.23'))

To use that I have to define a little function:

In [44]: def foo(astr):
    try:
        return int(astr)
    except ValueError:
        return float(astr)
   ....:     
In [45]: [[foo(x) for x in l[0].split()] for l in ll]
Out[45]: [[25, 1, 100.5, 2, 300], [50, 3, 125.5, 4, 85]]

In this case only the middle strings appear as floats.

Upvotes: 0

user5590296
user5590296

Reputation:

list = [['25 1 100.5 2 300'], ['50 3 125.5 4 85']]
new_list = []
for x in list:
  new_list.append([float(y) for y in x[0].split(" ")])

This will convert all the numbers to floats. Of course it is assuming that you have only one string with numbers per list.

Good luck.

Upvotes: 1

Related Questions