tags:

views:

105

answers:

5

hi, I have a dict

val_dict - {'val1': 'abcd', 'val': '1234', 'val3': '1234.00', 'val4': '1abcd 2gfff'}

All the values to my keys are string.

So my question is how to find out type for my values in the dict.

I mean if i say`int(val_dict['val1']) will give me error.

Basically what I am trying to do is find out if the string is actual string or int or float.`

if int( val_dict['val1'):
dosomething
else if float(val_dict['val1']):
dosomething

thanks

A: 
raceCh-
The trouble here is that `type()` will always return `str` for the data as given. The poster wants to know if there's a way to determine the type of what the string represents.
eswald
+3  A: 

Maybe this:

is_int = True
try:
    as_int = int (val_dict['val1'])
except ValueError:
    is_int = False
    as_float = float (val_dict['val1'])

if is_int:
    ...
else:
    ...

You can get rid of is_int, but then there will be a lot of code (all float value handling) in try...except and I'd feel uneasy about that.

doublep
Also, pay attention to comment by S. Lott. Maybe you don't even need this and instead can improve the dictionary.
doublep
A: 

A simple solution, if you don't have too many formats, could involve checking the format of each value.

def intlike(value):
    return value.isdigit()
def floatlike(value):
    import re
    return re.match("^\d+\.\d+$")

if intlike(val_dict['val1']):
    dosomething(int(val_dict['val1']))
elif floatlike(val_dict['val1']):
    somethingelse(float(val_dict['val1']))
else:
    entirelydifferent()

However, it really is easier to use Python's exception framework for certain complex formats:

def floatlike(value):
    try:
        float(value)
    except ValueError:
        result = False
    else:
        result = True
    return result
eswald
You don't need to use a regex to match a float, and your regex won't match all possible floats either. Python can coerce '0.' and '.0' as a float, while + is a match for "one or more of the preceding".
lunixbochs
@lunixbochs: That's why I recommended the exception framework instead. However, if the data is coming from a known source, that regex may very well always match on float values; it certainly looks like the "+" is correct on the right-hand side, for example. In addition, this offers a way to check possibilities that weren't explicitly requested in the question; for example, another regex could identify the '1abcd 2gfff' as a list.
eswald
+2  A: 

All the values are of course "actual strings" (you can do with them all you can possibly do with strings!), but I think most respondents know what you mean -- you want to try converting each value to several possible types in turn ('int' then 'float' is specifically what you name, but couldn't there be others...?) and return and use the first conversion that succeeds.

This is of course best encapsulated in a function, away from your application logic. If the best match for your needs is just to do the conversion and return the "best converted value" (and they'll all be used similarly), then:

def best_convert(s, types=(int, float)):
  for t in types:
    try: return t(s)
    except ValueError: continue
  return s

if you want to do something different in each case, then:

def dispatch(s, defaultfun, typesandfuns):
  for t, f in typesandfuns:
    try: 
      v = t(s)
    except ValueError:
      continue
    else:
      return f(v)
  return defaultfun(s)

to be called, e.g, as

r = dispatch(s, asstring, ((int, asint), (float, asfloat)))

if the functions to be called on "nonconvertible strings", ones convertible to int, and ones convertible to float but not int, are respectively asstring, asint, asfloat.

I do not recommend putting the "structural" "try converting to these various types in turn and act accordingly" code in an inextricable mixture with your "application logic" -- this is a clear case for neatly layering the two aspects, with good structure and separation.

Alex Martelli
A: 

you can determine if the string will convert to an int or float very easily, without using exceptions

# string has nothing but digits, so it's an int
if string.isdigit():
    int(string)

# string has nothing but digits and one decimal point, so it's a float
elif string.replace('.', '', 1).isdigit():
    float(string)
lunixbochs