5

So, I'm trying to be a good Python programmer and duck-type wherever I can, but I've got a bit of a problem where my input is either a dict or a list of dicts.

I can't distinguish between them being iterable, because they both are.

My next thought was simply to call list(x) and hope that returned my list intact and gave me my dict as the only item in a list; alas, it just gives me the list of the dict's keys.

I'm now officially out of ideas (short of calling isinstance which is, as we all know, not very pythonic). I just want to end up with a list of dicts, even if my input is a single solitary dict.

4

5 回答 5

6

真的,没有明显的pythonic方法可以做到这一点,因为它是一种不合理的输入格式,而明显的pythonic方法就是修复输入......</p>

但是如果你不能这样做,那么是的,你需要编写一个适配器(尽可能靠近输入边缘)。最好的方法取决于实际数据。如果它确实是一个 dict 或一个 dicts 列表,并且没有其他可能(例如,您正在调用json.loads一些返回对象或对象数组的编写错误的服务的结果),那么就没有错与isinstance.

如果你想让它更通用一点,你可以使用适当的ABCs。例如:

if isinstance(dict_or_list, collections.abc.Mapping):
    return [dict_or_list]
else:
    return dict_or_list

但是,除非您有充分的理由需要这种普遍性,否则您只是隐藏了这个骇人听闻的解决方法,而您最好保持它尽可能可见。例如,如果它json.loads来自某个远程服务器,那么处理Mapping不是 a 的 adict是没有用的,对吧?

(如果您正在使用一些第三方客户端库,它只返回“类似 dict 的东西”或“类似列表的东西,包含类似 dict 的东西”,那么是的,使用 ABC。或者,如果该库甚至没有支持正确的 ABC,您可以编写尝试特定方法的代码,keys例如

于 2013-08-09T01:06:09.660 回答
3

dict使用非键访问 aint将获得一个项目或一个KeyError. 它会给你TypeError一个list. 所以你可以使用异常处理:

def list_dicts(dict_or_list):
    try:
        dict_or_list[None]
        return [dict_or_list]  # no error, we have a dict
    except TypeError:
        return dict_or_list    # wrong index type, we have a list
    except Exception:
        return [dict_or_list]  # probably KeyError but catch anything to be safe

无论它是 a还是 a list,这个函数都会给你a 。(如果它得到一个,它会从中列出一个项目。)这在类型方面也应该是相当安全的;如果它们没有类似的行为,其他类似或类似的对象可能会被认为是损坏的。dictslistdictdictdictlist

于 2013-08-09T02:31:03.730 回答
1

您可以检查是否存在items属性。

dict有和list没有。

>>> hasattr({}, 'items')
True

>>> hasattr([], 'items')
False

dict这是和list(在 Python 3.3.2 中)之间属性名称差异的完整列表。

属性 onlist但不是dict

>>> print('\n'.join(sorted(list(set(dir([])) - set(dir({}))))))
__add__
__iadd__
__imul__
__mul__
__reversed__
__rmul__
append
count
extend
index
insert
remove
reverse
sort

属性 ondict但不是list

>>> print('\n'.join(sorted(list(set(dir({})) - set(dir([]))))))
fromkeys
get
items
keys
popitem
setdefault
update
values
于 2014-11-27T18:28:49.603 回答
0

也许我很天真,但是像这样的东西怎么样

try:
    data.keys()
    print "Probs just a dictionary"    
except AttributeError:
    print "List o' dictionaries!"

您能否继续对数据做任何您想做的事情,并在出现问题时决定它是字典还是列表?

于 2013-08-09T01:14:52.657 回答
-1

不要使用类型模块:

import types

d = {}
print type(d) is types.DictType

l = [{},{}]
print type(l) is types.ListType and len(l) and type(l[0]) is types.DictType
于 2013-08-09T01:51:08.767 回答