简体   繁体   English

如何在 Python 中实现这个 for 循环

[英]How to implement this for loop in Python

Im trying to implement Radix Sort in Python.我试图在 Python 中实现基数排序。 In the main Radix Sort function there is a for loop like this:在主基数排序 function 中有一个这样的 for 循环:

m = Maximum element in a given array
for(p = 1; m/p > 0; p*10)
{
    do stuff;
}

i did implement it using a while loop like below:我确实使用如下的while循环来实现它:

p = 1
while m / p > 0:
    p *= 10
    do stuff;

But since for loop is faster than while loop, I wonder how to implement that pseudocode in Python with a for loop.但由于 for 循环比 while 循环快,我想知道如何使用 for 循环在 Python 中实现该伪代码。 Any suggestions?有什么建议么?

Note: Radix Sort uses counting sort to sort based on digits starting from the right most digit (p=1) to the last digit and that's why for loop is used.注意:基数排序使用计数排序基于从最右边的数字(p=1)到最后一个数字的数字进行排序,这就是使用 for 循环的原因。

Logarithms are probably your answer.对数可能是你的答案。 Don't be surprised though, if it wants to repeat like 13.0983 times or something.不过,如果它想重复 13.0983 次之类的,请不要感到惊讶。 Also, unless m changes values, the while loop will forever run because it never will be 0 (unless there is rounding).此外,除非 m 更改值,否则 while 循环将永远运行,因为它永远不会为 0(除非有舍入)。

You also could just do:你也可以这样做:

for i in int((large p number calculated with while loop)/m):
    #code

Edit 1:编辑1:

So I was curious and implemented the three discussed approches:所以我很好奇并实施了三个讨论的方法:

import time 
import dis
import math

m = 100
p = 1.0
print(f'm:{m}, p:{p}')

print('-- For range - log')
c = 0
start = time.process_time()
for _ in range(int(math.log10(m))+1):
    c += 1
end = time.process_time() - start
print(f'c: {c}')
print(f'time: {end}')
c = compile('for _ in range(int(math.log10(m))+1):\n\tc += 1', '<string>', 'exec')
dis.dis(c)

print('-- For range - str len')
c = 0
start = time.process_time()
for _ in range(len(str(int(m)))):
    c += 1
end = time.process_time() - start
print(f'c: {c}')
print(f'time: {end}')
c = compile('for _ in range(len(str(int(m)))):\n\tc += 1', '<string>', 'exec')
dis.dis(c)

print('-- While loop')
c = 0
start = time.process_time()
while int(m / p) > 0:
    p *= 10
    c += 1
end = time.process_time() - start
print(f'c: {c}')
print(f'time: {end}')
c = compile('while int(m / p) > 0:\n\tp *= 10\n\tc += 1', '<string>', 'exec')
dis.dis(c)

Which results on my machine to:我的机器上的结果是:

  -- For range - log
  c: 3
  time: 7.000000000000062e-06
    1           0 LOAD_NAME                0 (range)
                2 LOAD_NAME                1 (int)
                4 LOAD_NAME                2 (math)
                6 LOAD_METHOD              3 (log10)
                8 LOAD_NAME                4 (m)
               10 CALL_METHOD              1
               12 CALL_FUNCTION            1
               14 LOAD_CONST               0 (1)
               16 BINARY_ADD
               18 CALL_FUNCTION            1
               20 GET_ITER
          >>   22 FOR_ITER                12 (to 36)
               24 STORE_NAME               5 (_)

    2          26 LOAD_NAME                6 (c)
               28 LOAD_CONST               0 (1)
               30 INPLACE_ADD
               32 STORE_NAME               6 (c)
               34 JUMP_ABSOLUTE           22
          >>   36 LOAD_CONST               1 (None)
               38 RETURN_VALUE
  -- For range - str len
  c: 3
  time: 2.9999999999960614e-06
    1           0 LOAD_NAME                0 (range)
                2 LOAD_NAME                1 (len)
                4 LOAD_NAME                2 (str)
                6 LOAD_NAME                3 (int)
                8 LOAD_NAME                4 (m)
               10 CALL_FUNCTION            1
               12 CALL_FUNCTION            1
               14 CALL_FUNCTION            1
               16 CALL_FUNCTION            1
               18 GET_ITER
          >>   20 FOR_ITER                12 (to 34)
               22 STORE_NAME               5 (_)

    2          24 LOAD_NAME                6 (c)
               26 LOAD_CONST               0 (1)
               28 INPLACE_ADD
               30 STORE_NAME               6 (c)
               32 JUMP_ABSOLUTE           20
          >>   34 LOAD_CONST               1 (None)
               36 RETURN_VALUE
  -- While loop
  c: 3
  time: 2.9999999999960614e-06
    1     >>    0 LOAD_NAME                0 (int)
                2 LOAD_NAME                1 (m)
                4 LOAD_NAME                2 (p)
                6 BINARY_TRUE_DIVIDE
                8 CALL_FUNCTION            1
               10 LOAD_CONST               0 (0)
               12 COMPARE_OP               4 (>)
               14 POP_JUMP_IF_FALSE       34

    2          16 LOAD_NAME                2 (p)
               18 LOAD_CONST               1 (10)
               20 INPLACE_MULTIPLY
               22 STORE_NAME               2 (p)

    3          24 LOAD_NAME                3 (c)
               26 LOAD_CONST               2 (1)
               28 INPLACE_ADD
               30 STORE_NAME               3 (c)
               32 JUMP_ABSOLUTE            0
          >>   34 LOAD_CONST               3 (None)
               36 RETURN_VALUE

Seems like the generator approach with string count as opposed to logarithm calculation is the fastes.似乎使用字符串计数而不是对数计算的生成器方法是最快的。 My intution was that the while loop might be faster than the generator functions.我的直觉是 while 循环可能比生成器函数更快。 Turns out, its about 3 times slower.事实证明,它慢了大约 3 倍。

Fascinating.迷人。

Original Answer:原答案:

I assume the statement that for loops are faster than while loops is an untested hypothesis.我假设 for 循环比 while 循环快的说法是一个未经检验的假设。 So why not test it?那么为什么不测试呢?

Put your implementations in a timed block:将您的实现放在一个定时块中:

import time
start = time.process_time()

# your code here    

end = time.process_time() - start
print(end)

Well after doing a research on the loops topic, i found that using a string instead of doing calculation is much faster.在对循环主题进行研究之后,我发现使用字符串而不是进行计算要快得多。 It is not the correct answer but it is the fastest implementation in Python.这不是正确的答案,但它是 Python 中最快的实现。

for _ in range(len(str(m)):
    do stuff

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM