0

I have a dictionary "metadata" that contains key-value pairs of strings, lists, dicts, and integers. How can I loop through this dictionary and convert all values that are not of type string or integer to string?

Is there any way to simultaneously remove keys for which the value is empty? How could I do this without adding an additional loop?

4
  • 2
    The second part of your question is the same as what you asked on an earlier question. As for the rest, what have you tried? The answer to that earlier question should give you a good start on the general task of fiddling with dict contents. Commented Aug 25, 2012 at 21:34
  • Or more generally, any type that's not a string or integer should be converted to string. Commented Aug 25, 2012 at 21:35
  • @BrenBarn: I'm not sure how to detect types that are not integer or string. I'm also not sure how this integrates into the one-liner from the previous answer. Right now I'm doing 2 iterations (inefficient) and am looking for specific data types (list + dict) but I'd rather find a more general solution that's everything except int + string. Commented Aug 25, 2012 at 21:39
  • 2
    Sounds like the key thing to learn about is the isinstance function. Commented Aug 25, 2012 at 21:42

2 Answers 2

3

Use isinstance to check the type of a value. In Python 3, you can simply write:

{k:v if isinstance(v, (str, int)) else str(v) for k,v in dct.items() if k != ''}

In older Python versions, you must be aware that there are no dictionary comprehensions (<2.7), and that there are multiple types that could be built-in ints and strings(<3). If you mean character strings when you talk about strings, the 2.5-2.7 equivalent would be

dict((k, v if isinstance(v, (unicode, int, long)) else unicode(v))
     for k,v in dct.iteritems())
Sign up to request clarification or add additional context in comments.

2 Comments

Great solution (+1) but curious: why use isinstance vs type?
Because isinstance will match subclasses. For example, if someone chooses to implement OptimizedString with a string that's faster than Python's built-in one (say, because they always know the encoding in their application, or the string is connected to network processing, or shared with TCL, etc.), this will still work. numpy's integer types are still valid ints. Checking with type(v) in ... would miss these subclasses.
1

This works:

d={'l':[1,2,3],'s':'abc','i':5,'f':1.23,'di':{1:'one',2:'two'},'emty':''}
{k:v if type(v) in (str,int, long,unicode) else repr(v) for k,v in d.items() if v!=''} 

Prints:

{'i': 5, 's': 'abc', 'di': "{1: 'one', 2: 'two'}", 'l': '[1, 2, 3]', 'f': '1.23'}

1 Comment

? This converts everything to its repr, which won't leave ints alone, and adds an extra quote to the strings (e.g. "abc" becomes "'abc'"). And if v will remove any 0 integers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.