使用字典 get() 作为函数从地图创建 Python 列表与使用 for 循环创建字典 get() 列表

Posted

技术标签:

【中文标题】使用字典 get() 作为函数从地图创建 Python 列表与使用 for 循环创建字典 get() 列表【英文标题】:Creating a Python list from a map using dictionary get() as a function vs creating a dictionary get() list with a for loop 【发布时间】:2020-12-30 13:26:18 【问题描述】:

令我惊讶的是,看似更简单、负担更少的功能却效率更低。

我对两种方法进行了测试,10000 a-j(随机)字符长的字符串为word旧函数是a,新函数是b

def a(word):
dictionary = "a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8, "i": 9, "j": 10,
word = list(map(dictionary.get, list(word)))
return word

def b(word):
dictionary = "a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8, "i": 9, "j": 10,
word = [dictionary.get(l, l) for l in word]
return word

map 与 for 循环相比应该具有微小的速度优势:https://***.com/a/1247490/12494235。但是,就我而言,优势是显着的。在函数b 中执行了更多操作,并且始终需要多花 0.001-0.003 秒。此外,将可迭代的地图转换为列表应该会减慢a

A - 使用字典 get() 作为函数从地图创建列表

         160 function calls (159 primitive calls) in 0.002 seconds

   Ordered by: call count
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       12    0.000    0.000    0.000    0.000 method 'rstrip' of 'str' objects
        7    0.000    0.000    0.000    0.000 method 'join' of 'str' objects
        6    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:222(_verbose_message)
        6    0.000    0.000    0.000    0.000 built-in method builtins.getattr
        ...

B - 创建一个带有 for 循环的字典 get() 列表

         10161 function calls (10160 primitive calls) in 0.004 seconds

   Ordered by: call count
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    10002    0.001    0.000    0.001    0.000 method 'get' of 'dict' objects
       12    0.000    0.000    0.000    0.000 method 'rstrip' of 'str' objects
        7    0.000    0.000    0.000    0.000 method 'join' of 'str' objects
        6    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:222(_verbose_message)
        6    0.000    0.000    0.000    0.000 built-in method builtins.getattr
        ...

这怎么可能?在分析这两者时我做错了什么吗?为什么 for 循环如此低效?

【问题讨论】:

【参考方案1】:

例如,如果您有 arr1arr2,则两者的长度 n = 10^9。

def A:
   for i in range(n):
      arr1[i] = 1
      arr2[i] = 2

def B:
   for i in range(n):
      arr1[i] = 1

   for i in range(n):
      arr2[i] = 2

您应该认为A 应该比B 快,但事实并非如此……因为在A 的情况下,编译器需要从arr1 ptr 跳转到arr2 ptr iter。甚至B 也有 2 个,但首先只为 arr1 调用该操作,然后只为 arr2 调用该操作 - 它非常有效。 所以一切都取决于方法是如何实现的,编译器是如何工作的,或者正在处理什么对象,以及它是如何保存在内存中的。 希望你能明白为什么for loop 应该如此低效...

【讨论】:

嘿德维!感谢您的回复,但我不确定我是否理解您的观点。你是说我在我的例子中实现了一个低效的 for 循环?

以上是关于使用字典 get() 作为函数从地图创建 Python 列表与使用 for 循环创建字典 get() 列表的主要内容,如果未能解决你的问题,请参考以下文章

Numpy:使用字典作为地图有效地替换二维数组中的值

从安装地图的阵列中检索信息(MapKit)

python函数

从列表中的项目创建字典

python中字典的get方法疑问?

空字典作为 dict.get() 的默认值