[英]What's the pythonic way to distinguish between a dict and a list of dicts?
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 dict
s. 所以,我试图成为一名优秀的Python程序员并尽可能地使用duck-type,但我有一个问题,我的输入是
dict
还是dict
list
。
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; 我的下一个想法只是调用
list(x)
并希望将我的列表完整地返回并将我的dict作为列表中唯一的项目给我; alas, it just gives me the list of the dict's keys. 唉,它只是给了我dict键的列表。
I'm now officially out of ideas (short of calling isinstance
which is, as we all know, not very pythonic). 我现在正式没有想法(缺少调用
isinstance
,我们都知道,这不是非常pythonic)。 I just want to end up with a list of dicts, even if my input is a single solitary dict. 我只想得到一个dicts列表,即使我的输入是一个单独的dict。
Really, there is no obvious pythonic way to do this, because it's an unreasonable input format, and the obvious pythonic way to do it is to fix the input… 实际上,没有明显的pythonic方法可以做到这一点,因为它是一种不合理的输入格式,明显的pythonic方法是修复输入...
But if you can't do that, then yes, you need to write an adapter (as close to the input edge as possible). 但是如果你不能这样做,那么是的,你需要编写一个适配器(尽可能靠近输入边缘)。 The best way to do that depends on the actual data.
最好的方法取决于实际数据。 If it really is either a dict, or a list of dicts, and nothing else is possible (eg, you're calling
json.loads
on the results from some badly-written service that returns an object or an array of objects), then there's nothing wrong with isinstance
. 如果它确实是一个dict或一个
json.loads
列表,那么其他任何东西都是不可能的(例如,你在一些写得很糟糕的服务返回一个对象或一组对象的结果上调用json.loads
),那么isinstance
没有任何问题。
If you want to make it a bit more general, you can use the appropriate ABCs . 如果你想使它更通用一点,你可以使用适当的ABCs 。 For example:
例如:
if isinstance(dict_or_list, collections.abc.Mapping):
return [dict_or_list]
else:
return dict_or_list
But unless you have some good reason to need this generality, you're just hiding the hacky workaround, when you're better off keeping it as visible as possible. 但除非你有充分的理由需要这种普遍性,否则你只是隐藏了hacky的解决方法,当你最好尽可能保持它的可见性时。 If it's, eg, coming out of
json.loads
from some remote server, handling a Mapping
that isn't a dict
is not useful, right? 如果它是,例如,来自某个远程服务器的
json.loads
,处理不是dict
的Mapping
是json.loads
,对吧?
(If you're using some third-party client library that just returns you "something dict-like" or "something list-like containing dict-like things", then yes, use ABCs. Or, if that library doesn't even support the proper ABCs, you can write code that tries a specific method like keys
. But if that's an issue, you'll know the specific details you're working around, and can code and document appropriately.) (如果你正在使用一些第三方客户端库,只返回“类似dict的东西”或“类似于dict的东西的列表”,那么是的,使用ABCs。或者,如果那个库甚至没有支持正确的ABC,您可以编写尝试特定方法(如
keys
代码。但如果这是一个问题,您将知道您正在解决的具体细节,并且可以适当地编码和记录。)
Accessing a dict
using a non- int
key will get you either an item, or a KeyError
. 使用非
int
键访问dict
将获得一个项目或KeyError
。 It will get you a TypeError
with a list
. 它将为您提供带有
list
的TypeError
。 So you can use exception handling: 所以你可以使用异常处理:
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
This function will give you a list
of dicts
regardless of whether it got a list
or a dict
. 这个功能会给你一个
list
的dicts
不管它是否有一个list
或dict
。 (If it got a dict
, it makes a list of one item out of it.) This should be fairly safe type-wise, too; (如果它有一个
dict
,它会列出一个项目的列表。)这在类型方面也应该是相当安全的; other dict
-like or list
-like objects would probably be considered broken if they didn't have similar behavior. 如果他们没有类似的行为,那么其他类似
dict
或类似list
的对象可能会被视为已损坏。
You could check for the presence of an items
attribute. 您可以检查是否存在
items
属性。
dict
has it and list
does not. dict
有它, list
没有。
>>> hasattr({}, 'items')
True
>>> hasattr([], 'items')
False
Here's a complete list of the differences in attribute names between dict
and list
(in Python 3.3.2). 这是
dict
和list
之间属性名称差异的完整列表(在Python 3.3.2中)。
Attributes on list
but not dict
: list
属性但不是dict
:
>>> print('\n'.join(sorted(list(set(dir([])) - set(dir({}))))))
__add__
__iadd__
__imul__
__mul__
__reversed__
__rmul__
append
count
extend
index
insert
remove
reverse
sort
Attributes on dict
but not list
: dict
属性但没有list
:
>>> print('\n'.join(sorted(list(set(dir({})) - set(dir([]))))))
fromkeys
get
items
keys
popitem
setdefault
update
values
Maybe I'm being naive, but how about something like 也许我很天真,但是怎么样
try:
data.keys()
print "Probs just a dictionary"
except AttributeError:
print "List o' dictionaries!"
Can you just go ahead and do whatever you were going to do anyways with the data, and decide whether it's a dict or list when something goes awry? 您是否可以继续使用数据做任何您要做的事情,并在出现问题时判断它是否是字典或列表?
Don't use the types module: 不要使用类型模块:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.