简体   繁体   中英

How to convert string in list of lists to float in place?

my_list=[['A','B','C','0.0'],['D','E','F','1.0'],['G','H','I','0'],['J','K','L','M']

I've tried doing

new_list=[[float(x) for x in i if x.isnumeric()] for i in my_list]

Output

[[0.0],[1.0],[0],[]]

Expected output

[['A','B','C',0.0],['D','E','F',1.0],['G','H','I',0],['J','K','L','M']

I don't know how to turn the final values into a float and modify the values in place, I've tried appending. I've tried the answers to other questions too but they created a new list, but I want to change the original list.

EDIT Changed my list to include decimals. The below answers worked if the numbers (string) were '0' but not decimals '0.0' or '1.0'.

You need to keep x if x is not numeric. You are close:

>>> my_list = [['A','B','C','0'], ['D','E','F','1'], ['G','H','I','J']]
>>> new_list = [[float(x) if x.isnumeric() else x for x in i] for i in my_list]
>>> new_list
[['A', 'B', 'C', 0.0], ['D', 'E', 'F', 1.0], ['G', 'H', 'I', 'J']]

Note the if x.isnumeric() else x inside the list comprehension, and that it's at the beginning of the comprehension, not the end (since it's a ternary conditional)


As you've noticed, this is creating a new list, not modifying the original. If you want to keep the original list, a basic for-loop would be better:

for i, sublist in enumerate(my_list):
    for j, x in enumerate(sublist):
        try:
            my_list[i][j] = float(x)
        except ValueError:
            pass

[['A', 'B', 'C', 0.0], ['D', 'E', 'F', 1.0], ['G', 'H', 'I', 'J']]

Assign to my_list[:] to modify it inplace. Use a ternary if instead of the comprehensions if filter to keep all items.

#       v modify list instead of replacing it
my_list[:] = [[float(x) if x.isnumeric() else x for x in i] for i in my_list]
#                       ^ ternary if provides a value for each element

If the nested lists must be modified in-place, consider using a loop to explicitly access each sub-list. If memory consumption is a goal, use a generator expression ( (...) ) instead of a list comprehension ( [...] ) for the new elements.

for sub_list in my_list:
    sub_list[:] = (float(x) if x.isnumeric() else x for x in sub_list)

To convert all float values, not just those that are purely digits, use try - except . str.isnumeric will for example reject '12.3' .

def try_float(literal: str):
    try:
        return float(literal)
    except ValueError:
        return literal

for sub_list in my_list:
    sub_list[:] = (try_float(x) for x in sub_list)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM