【问题标题】:What's the most elegant way to write this for loop in Python?在 Python 中编写这个 for 循环的最优雅的方法是什么?
【发布时间】:2012-01-02 03:26:39
【问题描述】:

基本上我想在n 步骤中从-1 到1,包括-1 和1:

x = -1.0
n = 21

for i in range(n):
    print x
    x += 0.01

-1.0 -0.9 -0.8 ... 0.8 0.9 1.0

对于任何n 值,我怎样才能以最优雅、最简单的方式编写此代码?

【问题讨论】:

标签: python math loops for-loop


【解决方案1】:

没有内置的解决方案,但可能解决它的好方法是定义自己的range 函数:

def my_range(start, end, how_many):
    incr = float(end - start)/(how_many - 1)
    return [start + i*incr for i in range(how_many)]

你可以在for循环中使用它:

>>> for i in my_range(-1, 1, 10):
...   print i
... 
-1.0
-0.777777777778
-0.555555555556
-0.333333333333
-0.111111111111
0.111111111111
0.333333333333
0.555555555556
0.777777777778
1

编辑:正如@NiklasBaumstark 所建议的,如果您全新的my_range 函数要处理大量数字,那么使用generators 可能是个好主意。为此,我们只做一点修改:

def my_xrange(start, end, how_many):
        incr = float(end - start)/(how_many - 1)
        return (start + i*incr for i in xrange(how_many))

【讨论】:

  • 你真的应该在那里使用生成器,而不是创建一个临时列表。
  • @NiklasBaumstark:你完全正确,我会把它添加到我的答案中
【解决方案2】:

如果可以使用numpy,则可以正常使用:

import numpy as np
n = 21

for i in np.linspace(-1, 1, n):
    print i

【讨论】:

    【解决方案3】:
    startValue = -1.0
    intervalLength = 2.0
    numberOfSteps = 14
    increasePerStep = intervalLength / numberOfSteps
    
    print startValue
    
    x = startValue
    for i in range (numberOfSteps):
        x += increasePerStep
        print x
    
    
    -1.0
    -0.857142857143
    -0.714285714286
    -0.571428571429
    -0.428571428571
    -0.285714285714
    -0.142857142857
    -2.22044604925e-16
    0.142857142857
    0.285714285714
    0.428571428571
    0.571428571429
    0.714285714286
    0.857142857143
    1.0
    

    【讨论】:

    • 迈克尔,你为什么要删除这个?我用这个,它似乎工作。这个有潜在问题吗? :O
    • @JoanVenge 我以为我看到了问题,然后一分钟前重新检查,发现没有问题,所以我取消了它。
    • 这比@JoanVenge 提出的那个更优雅?两者都有magic numbers0.012.0
    • “都有神奇的数字(0.01 和 2.0)”更神奇的是14
    • 对不起,伙计们,我接受了这个,因为我只需要一个简单的公式来处理这种情况,而不是一个适用于其他人的公式,因为我很少需要这种东西,否则我会接受 Julio 的解决方案(我赞成)。
    【解决方案4】:

    我会选择

    for x in xrange(n):
        print float(2*x)/(n-1) - 1
    

    感兴趣的两件事:xrangerange 更高效,并且不需要有两个单独的迭代器变量。

    如果你发现它经常有用,你可以将它包装在一个函数中:

    def linspace1(n):
        for x in xrange(n):
            yield float(2*x)/(n-1) - 1
    

    尽管您可能也希望设置下限和上限参数,如 julio.alegria 的回答。

    【讨论】:

      【解决方案5】:

      你说你有你的答案,但我觉得这是一个优雅的解决方案。它还消除了奇怪的浮点问题的可能性(至少在定义的范围内)。它结合了生成器的强大功能和灵活性以及字符串格式和浮点值。或者,如果您选择使用 Decimal 模块,您可以避免大部分此类情况 - 但这需要更多调整。

      def decimal_stepper(start, end, step=0.1):
          while start <= end:
              yield float(start)
              start = float(('%' + str(step) + 'f') % (start+step))
      

      运行示例:

      myVals = decimal_stepper(-1, 1)
      for x in myVals:
          print x
      

      哪些输出:

      -1.0
      -0.9
      -0.8
      -0.7
      -0.6
      -0.5
      -0.4
      -0.3
      -0.2
      -0.1
      0.0
      0.1
      0.2
      0.3
      0.4
      0.5
      0.6
      0.7 
      0.8
      0.9
      1.0
      

      【讨论】:

        猜你喜欢
        • 2022-06-17
        • 1970-01-01
        • 2018-03-14
        • 2023-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-22
        • 2018-07-06
        相关资源
        最近更新 更多