doyz
doyz

Reputation: 886

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

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]]

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

Upvotes: 3

Views: 67

Answers (5)

smac89
smac89

Reputation: 43078

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]

Upvotes: 0

atru
atru

Reputation: 4744

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()).

Upvotes: 1

thejinx0r
thejinx0r

Reputation: 471

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)

Upvotes: 1

Imran
Imran

Reputation: 13458

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

Upvotes: 3

Julien
Julien

Reputation: 15071

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]

Upvotes: 1

Related Questions