什么是区分词典和词典列表的pythonic方法?

时间:2013-08-09 01:01:42

标签: python list dictionary

所以,我试图成为一名优秀的Python程序员并尽可能地使用duck-type,但是我有一个问题,我的输入是dict或{{1} } list s。

我无法区分它们是可迭代的,因为它们都是。

我的下一个想法只是打电话给dict并希望我的名单完整无缺,并将我的字典作为列表中唯一的项目给了我;唉,它只是给了我dict键的列表。

我现在正式没有想法(没有打电话给list(x),我们都知道,这不是非常pythonic)。我只想得到一个dicts列表,即使我的输入是一个单独的单词。

5 个答案:

答案 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

以下是dictlist之间属性名称差异的完整列表(在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