对在python中执行两个代码感到困惑?

时间:2017-12-30 03:11:11

标签: python python-3.x for-loop jupyter-notebook jupyter

代码1:

%%timeit
students = [['Zack',38],['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2], ['Akriti', 41], ['Harsh', 39]]
second_highest = sorted(list(set([x[1] for x in students])))[1]
([a for a,b in sorted(students) if b == second_highest])

代码2:

%%timeit
students = [['Zack',38],['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2], ['Akriti', 41], ['Harsh', 39]]
s = sorted(set([x[1] for x in students]))
for name in sorted(x[0] for x in students if x[1] == s[1]):
    name

enter image description here

现在我对两个程序的执行感到困惑,尽管在code2中使用嵌套for循环,但code2如何比代码code1快。下面的图片来自Jupyter笔记本,它显示了100000个循环的代码所需的平均时间。虽然差异很小但我感到很困惑,因为嵌套for循环的工作方式比单循环方式更快。<​​/ p>

我应该打印输出,所以可以在最后一行代码之前放置

2 个答案:

答案 0 :(得分:0)

这不是嵌套循环。

看来你错了这条线

for name in sorted(x[0] for x in students if x[1] == s[1]):
    name

在这里,您要创建一个生成器并将其传递给sorted函数

sorted(x[0] for x in students if x[1] == s[1])

首先计算一个列表。然后,在评估该表达式并获得列表之后,它由for循环迭代。所以它是两个循环,一个接一个,而不是嵌套。

答案 1 :(得分:0)

这是因为第二种情况下,生成器被传递到sorted()循环中的forsorted()函数首先复制序列,这个副本对于生成器列表要比列表列表慢,因为列表需要首先从生成器生成。请参阅this问题。因此,如果您通过列表替换生成器,它会变得更快。

In [11]: %%timeit
students = [['Zack',38],['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2], ['Akriti', 41], ['Harsh', 39]]
s = sorted(set([x[1] for x in students]))
for name in sorted([x[0] for x in students if x[1] == s[1]]):
    name
   ....: 
The slowest run took 5.71 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 4.72 µs per loop

In [6]: %%timeit                         
students = [['Zack',38],['Harry', 37.21], ['Berry', 37.21], ['Tina', 37.2], ['Akriti', 41], ['Harsh', 39]]
second_highest = sorted(list(set([x[1] for x in students])))[1]
([a for a,b in sorted(students) if b == second_highest])
   ...: 
The slowest run took 11.50 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.31 µs per loop