简体   繁体   English

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

[英]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 ,处理不是dictMappingjson.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 . 它将为您提供带有listTypeError 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 . 这个功能会给你一个listdicts不管它是否有一个listdict (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). 这是dictlist之间属性名称差异的完整列表(在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.

相关问题 什么是重新排序由dicts组成的列表的Pythonic方法? - What is the Pythonic way of reordering a list consisting of dicts? 迭代字典和列表的python方法是什么? - What is the Pythonic way to iterate over a dict of dicts and lists? 这个字典列出转换的pythonic方法是什么? - What is the pythonic way to this dict to list conversion? 在列表中设置字典字段的pythonic方法是什么 - What is the pythonic way of setting fields of a dict in a list 将列表的字典转换为字典中所有元素的所有组合的字典列表的最有效方法? - Most pythonic way to convert a dict of lists into a list of dicts of all combs of the elements in the lists from the dict? 在一系列dicts上进行以下转换的Pythonic方法是什么? - What is a Pythonic way of doing the following transformation on a list of dicts? 将键/值对的列表(或其他迭代器)添加到dict的Python方法是什么? - What's a Pythonic way to add a list (or other iterator) of key/value pairs to a dict? 如果其中一个值不是唯一的,从字典列表中删除元素的pythonic方法是什么? - What's the pythonic way to remove element from a list of dict if ONE of the values is not unique? 从 dict 创建 dict 列表的更多 Pythonic 方法,其中列表元素是形式为 `{v:[k1, k2, k3]}` 的 dict - More pythonic way to create list of dicts from dict where list elements are dict of form `{v:[k1, k2, k3]}` Pythonic将dicts列表转换为namedtuples列表的方法 - Pythonic way to convert list of dicts into list of namedtuples
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM