【发布时间】:2020-10-16 02:18:37
【问题描述】:
在dict.items()中检查成员的时间复杂度是多少?
键视图是类似集合的,因为它们的条目是唯一且可散列的。 如果所有值都是可散列的,那么 (key, value) 对是唯一的并且 可散列,然后项目视图也是类似集合的。(值视图不是 被视为类似集合,因为条目通常不是唯一的。)对于 类似集合的视图,为抽象基础定义的所有操作 类 collections.abc.Set 可用(例如,==、
所以我用下面的代码做了一些测试:
from timeit import timeit
def membership(val, container):
val in container
r = range(100000)
s = set(r)
d = dict.fromkeys(r, 1)
d2 = {k: [1] for k in r}
items_list = list(d2.items())
print('set'.ljust(12), end='')
print(timeit(lambda: membership(-1, s), number=1000))
print('dict'.ljust(12), end='')
print(timeit(lambda: membership(-1, d), number=1000))
print('d_keys'.ljust(12), end='')
print(timeit(lambda: membership(-1, d.keys()), number=1000))
print('d_values'.ljust(12), end='')
print(timeit(lambda: membership(-1, d.values()), number=1000))
print('\n*With hashable dict.values')
print('d_items'.ljust(12), end='')
print(timeit(lambda: membership((-1, 1), d.items()), number=1000))
print('*With unhashable dict.values')
print('d_items'.ljust(12), end='')
print(timeit(lambda: membership((-1, 1), d2.items()), number=1000))
print('d_items'.ljust(12), end='')
print(timeit(lambda: membership((-1, [1]), d2.items()), number=1000))
print('\nitems_list'.ljust(12), end='')
print(timeit(lambda: membership((-1, [1]), items_list), number=1000))
输出:
set 0.00034419999999998896
dict 0.0003307000000000171
d_keys 0.0004200000000000037
d_values 2.4773092
*With hashable dict.values
d_items 0.0004413000000003109
*With unhashable dict.values
d_items 0.00042879999999989593
d_items 0.0005549000000000248
items_list 3.5529328
如您所见,当dict.values 都是可散列的(int)时,
成员资格的执行时间类似于set 或d_keys,
因为items 视图类似于集合。
最后两个示例在 dict.values 上,带有不可散列的对象 (list)。
所以我假设执行时间与list 的执行时间相似。
但是,它们仍然类似于set。
这是否意味着即使dict.values 是不可散列的对象,
items view的实现还是很高效的,
结果 O(1) 检查成员的时间复杂度?
我错过了什么吗?
已编辑
根据@chepner 的评论:dict.fromkeys(r, [1]) -> {k: [1] for k in r}
已编辑
根据@MarkRansom 的评论:另一个测试用例list(d2.items())
【问题讨论】:
-
我认为
in不会检查成员资格的值,因此这些值是否可散列并不重要。 -
@MarkRansom 你是说python在内部只检查每个元组的第一项吗?
items返回一个包含(key, value)对的视图对象作为元组。 -
请记住,
dict.fromkeys(r, [1])创建一个只有一个 unique 值的dict;对于任意两个键x和y,d2[x] is d2[y]将为真。这可能是相关的。 -
@chepner 也许,我会尝试使用不同的对象。
-
@chepner 这不是问题所在。查看修改后的代码。
标签: python python-3.x dictionary time-complexity