所以,我试图成为一名优秀的Python程序员并尽可能地使用duck-type,但是我有一个问题,我的输入是dict
或{{1} } list
s。
我无法区分它们是可迭代的,因为它们都是。
我的下一个想法只是打电话给dict
并希望我的名单完整无缺,并将我的字典作为列表中唯一的项目给了我;唉,它只是给了我dict键的列表。
我现在正式没有想法(没有打电话给list(x)
,我们都知道,这不是非常pythonic)。我只想得到一个dicts列表,即使我的输入是一个单独的单词。
答案 0 :(得分:4)
实际上,没有明显的pythonic方法可以做到这一点,因为它是一种不合理的输入格式,明显的pythonic方法是修复输入......
但是如果你不能这样做,那么是的,你需要编写一个适配器(尽可能靠近输入边缘)。最好的方法取决于实际数据。如果它确实是一个dict或一个dicts列表,那么其他任何东西都是不可能的(例如,你在一些写得很糟糕的服务返回一个对象或一组对象的结果上调用json.loads
,那么isinstance
没有错。
如果您想让它更通用一点,您可以使用适当的ABCs。例如:
if isinstance(dict_or_list, collections.abc.Mapping):
return [dict_or_list]
else:
return dict_or_list
但除非你有充分的理由需要这种普遍性,否则你只是隐藏了hacky的解决方法,当你最好尽可能保持它的可见性时。如果它是,例如,来自某个远程服务器的json.loads
,处理不是Mapping
的{{1}}是没用的,对吗?
(如果您正在使用某些第三方客户端库,它只会返回“像dict一样的东西”或“类似于dict的东西的列表”,那么是的,使用ABCs。或者,如果该库不存在甚至不支持正确的ABC,您可以编写尝试特定方法的代码,例如dict
。但如果这是一个问题,您将知道您正在解决的具体细节,并且可以适当地编码和记录。 )
答案 1 :(得分:2)
使用非dict
密钥访问int
会获得一个项目或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
无论是list
还是dicts
,此功能都会为list
dict
提供dict
。 (如果它有一个dict
,它会列出一个项目的列表。)这在类型方面也应该是相当安全的;其他list
- 类似或{{1}}类似的对象如果没有相似的行为,可能会被视为已损坏。
答案 2 :(得分:0)
也许我天真,但是像
这样的东西try:
data.keys()
print "Probs just a dictionary"
except AttributeError:
print "List o' dictionaries!"
你可以继续做任何你想做的事情,然后决定当出现问题时它是否是一个字典或列表?
答案 3 :(得分:0)
您可以检查是否存在items
属性。
dict
拥有它而list
没有。
>>> hasattr({}, 'items')
True
>>> hasattr([], 'items')
False
以下是dict
和list
之间属性名称差异的完整列表(在Python 3.3.2中)。
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
dict
但不是list
的属性:
>>> print('\n'.join(sorted(list(set(dir({})) - set(dir([]))))))
fromkeys
get
items
keys
popitem
setdefault
update
values
答案 4 :(得分:-1)
不要使用types模块:
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