我正在编写一个 Django 应用程序,我将从用户那里获得一个大小可变的字典。我想限制字典的大小,即它可以容纳多少 (key, value)
对。我希望它不超过 200。我怀疑如果这样做:
if len(user_dict)>200:
raise ValidationError("dict has too many (key, value) pairs")
python 必须对整个字典进行计数。如果 dict 很大,因为恶意用户,这将消耗不必要的处理能力。或者 dict 是否跟踪它拥有多少个对象,这意味着 len(user_dict)
是一个简单的查找操作?解决此问题的最佳方法是什么?
我在想:
i=0
for key in user_dict.keys():
i += 1
if i>200:
raise ValidationError("dict has too many (key, value) pairs")
Or does the dict keep track of how many objects it holds, meaning len(user_dict)
is a simple lookup operation?
字典 - 给定像 CPython 这样的严肃的解释器实现 - 实际上会跟踪存储在字典中的键值对的数量。所以如果user_dict
确实是一个字典,那么len(user_dict)
在O(1)中工作并且非常快速地。它在恒定时间内工作的事实也意味着无论我们计算具有 100k 项的 dict
对象的 len(..)
没有(理论上的)区别,或者完全没有。
不需要迭代来计算对象的数量。例如 CPython source code for the dict
class has :
static Py_ssize_t
dict_length(PyDictObject *mp)
{
return mp->ma_used;
}
因此它返回字典对象的 ma_used
字段(因此这是一个包含字典中项目数的字段)。
this file 中也对此进行了描述:
Dictionaries: dict and defaultdict
Complexity
Operation | Example | Class | Notes
--------------+--------------+---------------+-------------------------------
Index | d[k] | O(1) |
Store | d[k] = v | O(1) |
Length | len(d) | O(1) |
Delete | del d[k] | O(1) |
get/setdefault| d.method | O(1) |
Pop | d.pop(k) | O(1) |
Pop item | d.popitem() | O(1) |
Clear | d.clear() | O(1) | similar to s = {} or = dict()
View | d.keys() | O(1) | same for d.values()
Construction | dict(...) | O(len(...)) | depends # (key,value) 2-tuples
Iteration | for k in d: | O(N) | all forms: keys, values, items