Reputation:
So I have this list here:
[['Afghanistan', '2.66171813', '7.460143566', '0.490880072', '52.33952713', '0.427010864', '-0.106340349', '0.261178523'], ['Albania', '4.639548302', '9.373718262', '0.637698293', '69.05165863', '0.74961102', '-0.035140377', '0.457737535'], ['Algeria', '5.248912334', '9.540244102', '0.806753874', '65.69918823', '0.436670482', '-0.194670126', ''], ['Argentina', '6.039330006', '9.843519211', '0.906699121', '67.53870392', '0.831966162', '-0.186299905', '0.305430293'], ['Armenia', '4.287736416', '9.034710884', '0.697924912', '65.12568665', '0.613697052', '-0.132166177', '0.246900991'], ['Australia', '7.25703764', '10.71182728', '0.949957848', '72.78334045', '0.910550177', '0.301693261', '0.45340696']]
My aim is to loop through the list of lists and convert number string values to integers.
I tried
for li in main_li:
for element in li:
if element == li[0]:
continue
else:
element = int(element)
My problem is how can I get this back into the same list format I had above without the numbers being strings.
Upvotes: 0
Views: 77
Reputation: 17911
You can use a star unpacking in a listcomp:
l = [['A', '1.1', '1.2'], ['B', '2.1', '2.2']]
[[i, *map(float, j)] for i, *j in l]
# [['A', 1.1, 1.2], ['B', 2.1, 2.2]]
Upvotes: 0
Reputation: 1699
Most of the answers assume a fixed level of nesting (list of lists). You could (if applicable) use the following code, which uses recursion of handle deeper nested lists (lists of lists of lists, etc).
def nested_str_to_float(value):
""" Converts an string to float. Value may be a single value, a list
or even a nested list. If value is a (nested) list, all
values in the (nested) list are evaluated to floats wherever possible.
Args:
value: single value of any type or a list
Returns:
a copy of value with all float-convertible items converted to float
"""
# Test if value is a list, if so, recursively call nested_str_to_float
if isinstance(value, list):
return [nested_str_to_float(item) for item in value]
# Try to convert to float; if possible, return float, else return value
try:
return float(value)
except ValueError:
return value
By the way, check this SO answer to see what Python considers floats...
Upvotes: 0
Reputation: 4538
Simply just convert those elements that are convertible to float and change them in current list with iterating through list index:
for i in range(len(main_li)):
for j in range(len(main_li[i])):
try:
main_li[i][j] = float(main_li[i][j])
except ValueError:
continue
li # [['Afghanistan', 2.66171813, 7.460143566, 0.490880072, 52.33952713, 0.427010864, -0.106340349, 0.261178523], ['Albania', 4.639548302, 9.373718262, 0.637698293, 69.05165863, 0.74961102, -0.035140377, 0.457737535], ['Algeria', 5.248912334, 9.540244102, 0.806753874, 65.69918823, 0.436670482, -0.194670126, ''], ['Argentina', 6.039330006, 9.843519211, 0.906699121, 67.53870392, 0.831966162, -0.186299905, 0.305430293], ['Armenia', 4.287736416, 9.034710884, 0.697924912, 65.12568665, 0.613697052, -0.132166177, 0.246900991], ['Australia', 7.25703764, 10.71182728, 0.949957848, 72.78334045, 0.910550177, 0.301693261, 0.45340696]]
Upvotes: 0
Reputation: 1841
You can do it by making a small change in your code
for li in main_li:
for i in range(1,len(li)):
try:
li[i] = int(li[i])
except ValueError:
pass
Upvotes: 2
Reputation: 4792
Your list elements are float so you can only convert them to float:
import re
pattern = re.compile('[-+]?\d+(\.\d+)?') # a pattern for all number types
new_list = []
for nest in l:
temp_list = []
for val in nest:
if bool(pattern.match(val)): #check if the element is a number
temp_list.append(float(val))
continue
temp_list.append(val)
new_list.append(temp_list)
print(new_list)
[['Afghanistan', 2.66171813, 7.460143566, 0.490880072, 52.33952713, 0.427010864, -0.106340349, 0.261178523], ['Albania', 4.639548302, 9.373718262, 0.637698293, 69.05165863, 0.74961102, -0.035140377, 0.457737535], ['Algeria', 5.248912334, 9.540244102, 0.806753874, 65.69918823, 0.436670482, -0.194670126, ''], ['Argentina', 6.039330006, 9.843519211, 0.906699121, 67.53870392, 0.831966162, -0.186299905, 0.305430293], ['Armenia', 4.287736416, 9.034710884, 0.697924912, 65.12568665, 0.613697052, -0.132166177, 0.246900991], ['Australia', 7.25703764, 10.71182728, 0.949957848, 72.78334045, 0.910550177, 0.301693261, 0.45340696]]
Upvotes: 1
Reputation: 5958
You shouldn't (not saying it's not possible) change list values while you loop over them. You'll have to create a new list. Fortunately, you can do it very easily with a small modification to your original code:
newlist = []
for li in main_li:
newli = []
for element in li:
if element == li[0]:
newli.append(element)
else:
try:
newli.append(int(float(element)))
except Exception as e:
newli.append(0) # This is added because not everything in your list can be converted to int.
newlist.append(newli)
newlist
will be your modified list of lists.
Alternatively, you can use list comprehension:
newlist = [[p[0]] + [int(float(x)) for x in p[1:]] for p in main_li]
Note how this requires all of your string to be correctly formatted.
Upvotes: 1