【问题标题】:Python : comprehension list, square brackets vs list()Python:理解列表,方括号与 list()
【发布时间】:2020-11-09 01:52:15
【问题描述】:

您好,我找不到使用方括号表示理解列表与使用 list() 之间的区别

是否存在性能/内存分配差异?

(对于 set 和 dict 相同的问题)

input = [1, 2, 3, 4]

B = [a * 2 for a in input if a > 1]

C = list(a * 2 for a in input if a > 1)

B_set = {str(a) for a in input if a > 1}

C_set = set(str(a) for a in input if a > 1)

B_dict = {str(a):a for a in input if a > 1}

C_dict = dict(str(a):b for a,b in input if a > 1) # NOT LEGAL

感谢您的帮助

【问题讨论】:

  • 好吧,list() 语法是创建一个生成器,而不是一个列表,然后list() 函数会将生成器变成一个列表。
  • 是的,存在性能差异。请参阅this 帖子。
  • @OlvinR​​oght 当然可以。
  • @OlvinR​​oght 结果是一样的;在每种情况下,到达那里的路径都大不相同。
  • 打个比方,列表推导直接调用input.__next__list() 必须调用生成器的__next__ 方法,然后再调用input.__next__

标签: python list-comprehension dictionary-comprehension set-comprehension


【解决方案1】:

我们可以联系-mtimeit

$ python -mtimeit "B = [a * 2 for a in list(range(1000)) if a > 1]"
5000 loops, best of 5: 86.7 usec per loop
$ python -mtimeit "B = list(a * 2 for a in list(range(1000)) if a > 1)"
2000 loops, best of 5: 110 usec per loop
$ python -mtimeit "B = list(a * 2 for a in list(range(1000)) if a > 1)"
2000 loops, best of 5: 110 usec per loop
$ python -mtimeit "B = {str(a): a for a in list(range(1000)) if a > 1}"
1000 loops, best of 5: 273 usec per loop
$ python -mtimeit "B = set(str(a) for a in list(range(1000)) if a > 1)"
1000 loops, best of 5: 287 usec per loop

所以,如您所见,没有太大区别。

有了更大的列表,我们有:

$ python -mtimeit "B = [a * 2 for a in list(range(100000)) if a > 1]"
20 loops, best of 5: 11.1 msec per loop
$ python -mtimeit "B = list(a * 2 for a in list(range(100000)) if a > 1)"
20 loops, best of 5: 14.2 msec per loop

我们看到 3 毫秒的差异,更适合 [] 的情况。

有了更大的数字列表,我们有

$ python -mtimeit "B = [a * 2 for a in list(range(10000000)) if a > 1]"
1 loop, best of 5: 1.21 sec per loop
$ python -mtimeit "B = list(a * 2 for a in list(range(10000000)) if a > 1)"
1 loop, best of 5: 1.49 sec per loop

我们看到 0.28 秒的差异,同样[] 更快。

【讨论】:

    【解决方案2】:

    您可以使用timeit 模块测量速度。

    例如:

    from timeit import timeit
    
    lst = [1, 2, 3, 4] * 100
    
    def fn1():
        return [a * 2 for a in lst if a > 1]
    
    def fn2():
        return list(a * 2 for a in lst if a > 1)
    
    t1 = timeit(lambda: fn1(), number=10_000)
    t2 = timeit(lambda: fn2(), number=10_000)
    
    print(t1)
    print(t2)
    

    打印(AMD 2400G,Python 3.8):

    0.2406109299918171
    0.2905043710197788
    

    所以列表理解更快。

    【讨论】:

      【解决方案3】:

      []list() 快得多,因为 []literal 意味着 python 直接编译和创建字节码,而 list() 是 object 需要名称解析、堆栈分配等,然后再创建字节码。

      【讨论】:

      • 不是这个原因。 list(<gen expression>) 与列表理解有根本的不同,尽管它会有效地产生相同的结果。性能差异主要是由于迭代生成器比列表推导式直接构建列表的方式慢。
      猜你喜欢
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2012-02-12
      • 2021-10-11
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多