Best way to distinguish between scalar, list and dict arguments in Python?
Question: I want a function that normally takes in an argument of type X where X is
either a scalar, a list, or a dict, and returns a list of X's with the same
key values, based on other information.

    
    
    def foo(info, k):
       return [bar(item,k) for item in processInfo(info)]
    
    def bar(item, keydata):
       # pseudocode follows.
       # What we want to do is return an output of parallel type to the input key k,
       # using the key data to lookup information from the input item.
       if keydata is a scalar:
          return item[keydata]
       elif keydata is a list:
          return [item[k] for k in keydata]
       elif keydata is a dict:
          return dict((k,item[v]) for (k,v) in keydata.iteritems())
       else:
          raise ValueError('bar expects a scalar, list, or dict')
    

My question is, how can I dispatch between the three types?

* * *

edit: A string is to be interpreted as a scalar, not a list/iterable. Tuples
are to be interpreted as iterable.

edit 2: I want duck typing, not strict typing.


Answer: You need to do things in the proper order since `str` and `dict` types are
iterable.

    
    
    from collections import Iterable, Mapping  # in Python 3 use from collections.abc
    
    def bar(item, keydata):
        if isinstance(keydata, Mapping):
            return {k: item[v] for (k,v) in keydata.iteritems()}
        elif isinstance(keydata, Iterable) and not isinstance(keydata, str):
            return [item[k] for k in keydata]
        return item[keydata]
    

