0

Let's say I have a dict like this:

[{'Chr': 'chrX', 'Start': '107844640', 'End': '107844640'}]

Almost all the key values are strings, not all of them, but almost (I don't know why).

I would like to check all the key values and convert the strings to int or float only if the string contains numbers. '10.020' should be a float, '10.020abc' should remain as a string and '123' should be an int.

This is the desired result:

[{'Chr': 'chrX', 'Start': 107844640, 'End': 107844640}]

I did something similar in JavaScript with Number().

Is there any pythonic way to achieve that?

Cheknov
  • 1,892
  • 6
  • 28
  • 55
  • Not really. You can implement your own `number()` function and use a dictionary comprehension to transform your dict. – Selcuk Apr 30 '21 at 01:31

5 Answers5

3

Create a nice little function to parse the keys/values:

def try_convert(x):
    try:
        return int(x)
    except ValueError:
        pass
    try:
        return float(x)
    except ValueError:
        return x

And now use it! For some dictionary d,

d = {try_convert(k): try_convert(v) for k, v in d.items()}
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
  • Note that this works with [anything that can be converted to float](https://stackoverflow.com/a/20929881/365102). That may or may not be exactly what you want. – Mateen Ulhaq Apr 30 '21 at 01:38
1

This should work:

original_values = [{'Chr': 'chrX', 'Start': '107844640', 'End': '107844640'}]

dictionary = original_values[0]
for key in dictionary:
    try:
        dictionary[key] = int(dictionary[key])
    except:
        try:
            dictionary[key] = float(dictionary[key])
        except:
            pass
output = [dictionary]
GabrielP
  • 777
  • 4
  • 8
1

The below code tries to convert the string to float, then checks if that's a integer and updates the original dictionary accordingly.

dict = {'Chr': 'chrX', 'Start': '107844640', 'End': '107844640.100'}
print('Before: ', dict)
for key, value in dict.items():
    try:
        v = float(value)
        if v.is_integer():
            v = int(v)
        d = {key: v}
        dict.update(d)
    except ValueError:
        continue

print('After: ', dict)

Output:

{'Chr': 'chrX', 'Start': '107844640', 'End': '107844640.100'}
{'Chr': 'chrX', 'Start': 107844640, 'End': 107844640.1}
Ishwar
  • 338
  • 2
  • 11
0

Give this a try.

dictEx = [{'Chr': 'chrX', 'Start': '107844640', 'End': '107844640.323'}]
for k in dictEx[0]:
    try:dictEx[0][k] = int(dictEx[0][k])
    except Exception as e:
        try:dictEx[0][k] = float(dictEx[0][k])
        except:pass 

We check if a value can be turned to int or float and change it based on that.

Buddy Bob
  • 5,829
  • 1
  • 13
  • 44
0

There are already some similar answers, but this would do the trick using a list comprehension without altering the original input.

def convert_value(value):
    try:
        v_float = float(value)
        if v_float.is_integer():
            return int(v_float)
        else:
            return v_float
    except ValueError:
        return value



input_l = [{'Chr': 'chrX', 'Start': '107844640', 'End': '107844640'},
           {'Chr': '126chrX', 'Start': '0.50', 'End': '1'}]
output_l = [{k: convert_value(v) for k,v in doc.items()} for doc in input_l]