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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With