Python 2.7: Format a list within a list using for loops

Viewed 54

Input:

data = [['A', 'B', 'C'], ['001', 'ddd', 'eee', '10'], ['002', 'fff', 'ggg', '20']]

Expected output:

data = ['A', 'B', 'C'], [1, 'ddd', 'eee', 10], [2, 'fff', 'ggg', 20]]
  • Convert columns with numerical values from strings to integers (with quotes around the numbers removed

I have attempted with the below code but I am getting this error:

ValueError: could not convert string to float: A

Could anyone point out my mistake?

formatted = []
for row in data:
    new_row = []
    for i, col in enumerate(row):
        if i != [1,2]:
            new_row.append(col)
            new_row.append(float(col))
    formatted.append(new_row)

print formatted
5 Answers

The 'pythonic' way to do this is to try converting each element to an integer, and fall back to keeping the string in case of failure.

formatted = []
for row in data:
    new_row = []
    for elem in row:
        try:
            new_row.append(int(elem))
        except ValueError:
            new_row.append(elem)
    formatted.append(new_row)

print formatted

What about this:

def to_float(s):
    try:
        return float(s)
    except:
        return s

[[to_float(s) for s in row] for row in data]

Your variable i, an integer, will never be equal to [1,2], a list. What you meant to say/write is:

if i not in [1,2]:

Edit: I forgot the first row. Since your first row is not like the others, either handle it differently (not recommended), or use one of the other answers (recommended)

You can apply a lambda function with a condition using map:

for i,d in enumerate(data):
    data[i] = map(lambda x: float(x) if x.isdigit() else x, d)

map applies the lambda function on every subelement of d. If the element is a string representing a digit, it applies conversion using float, if it is not, it leaves the whole string as it is. It directly replaces the sublist in data.

In Python 3.X the result of map would need to be explicitly converted to a list, i.e. data[i] = list(map()).

You can try by using json and regex as follows:

import json, re

data = [['A', 'B', 'C'], ['001', 'ddd', 'eee', '10'], ['002', 'fff', 'ggg', '20']]
data = json.dumps(data)
data = json.loads(re.sub(r'"0*(\d+)"', r'\1', data)

print (data)

Output:

[['A', 'B', 'C'], [1, 'ddd', 'eee', 10], [2, 'fff', 'ggg', 20]]

You also mentioned you wanted to remove commas after each list, well here is one way:

data = reduce(lambda oldList, newList: oldList + newList, data, [])

Output:

['A', 'B', 'C', 1, 'ddd', 'eee', 10, 2, 'fff', 'ggg', 20]
Related