【问题标题】:Pythonic way to write a for loop that doesn't use the loop index编写不使用循环索引的 for 循环的 Pythonic 方法
【发布时间】:2010-12-26 02:54:04
【问题描述】:

这与下面的代码有关,它使用一个 for 循环来生成一系列随机偏移量,以供程序中的其他地方使用。

这个 for 循环的索引未被使用,这导致“违规”代码被 Eclipse / PyDev 突出显示为警告

def RandomSample(count):    
    pattern = []
    for i in range(count):
        pattern.append( (random() - 0.5, random() - 0.5) )

    return pattern

所以我要么需要一种更好的方法来编写不需要循环索引的循环,要么需要一种方法来告诉 PyDev 忽略这个未使用变量的特定实例。

有人有什么建议吗?

【问题讨论】:

标签: eclipse for-loop python


【解决方案1】:

PyDev中忽略变量仅供参考

默认情况下pydev会忽略以下变量

['_', 'empty', 'unused', 'dummy']

你可以通过传递抑制参数来添加更多

-E, --unusednames  ignore unused locals/arguments if name is one of these values

参考: http://eclipse-pydev.sourcearchive.com/documentation/1.0.3/PyCheckerLauncher_8java-source.html

【讨论】:

  • PyDev 如果未使用的变量下划线开头,则会抑制警告。所以_i 也可以。
  • 您也可以添加“i=i”。这样做的好处是可以在任何开发环境中工作,而不管它有什么内置变量忽略它。
【解决方案2】:

itertools.repeat怎么样:

import itertools
count = 5
def make_pat():
    return (random() - 0.5, random() - 0.5)
list(x() for x in itertools.repeat(make_pat, count))

示例输出:

[(-0.056940506273799985, 0.27886450895662607), 
(-0.48772848046066863, 0.24359038079935535), 
(0.1523758626306998, 0.34423337290256517), 
(-0.018504578280469697, 0.33002406492294756), 
(0.052096928160727196, -0.49089780124549254)]

【讨论】:

  • 作为函数:fn = lambda count: itertools.repeat(lambda: (random() - 0.5, random() - 0.5), count)
【解决方案3】:
randomSample = [(random() - 0.5, random() - 0.5) for _ in range(count)]

count=10 的示例输出并假设您指的是标准库 random() 函数:

[(-0.07, -0.40), (0.39, 0.18), (0.13, 0.29), (-0.11, -0.15),\
(-0.49, 0.42), (-0.20, 0.21), (-0.44, 0.36), (0.22, -0.08),\
(0.21, 0.31), (0.33, 0.02)]

如果你真的需要把它变成一个函数,那么你可以使用lambda来缩写:

f = lambda count: [(random() - 0.5, random() - 0.5) for _ in range(count)]

这样你可以这样称呼它:

>>> f(1)
f(1)
[(0.03, -0.09)]
>>> f(2)
f(2)
[(-0.13, 0.38), (0.10, -0.04)]
>>> f(5)
f(5)
[(-0.38, -0.14), (0.31, -0.16), (-0.34, -0.46), (-0.45, 0.28), (-0.01, -0.18)]
>>> f(10)
f(10)
[(0.01, -0.24), (0.39, -0.11), (-0.06, 0.09), (0.42, -0.26), (0.24, -0.44) , (-0.29, -0.30), (-0.27, 0.45), (0.10, -0.41), (0.36, -0.07), (0.00, -0.42)]
>>> 

你懂的……

【讨论】:

  • 这只是将未使用的变量重命名为 _ ,因此实际上并没有更好,除非 Eclipse 专门忽略了这一点。
  • PyDev 不会给出关于 _ 未被使用的相同警告吗?
  • '_' 是一个虚拟变量,Eclipse 不应该抱怨,但我不知道,因为我从未在那个平台上开发过 Python。祝你好运,如果它确实抱怨,请告诉我。
  • 不,_ 没有收到警告。
  • @Adam:很高兴知道。感谢您告知我们。
【解决方案4】:

聚会迟到了,但这里有一个潜在的想法:

def RandomSample(count):
    f = lambda: random() - 0.5
    r = range if count < 100 else xrange # or some other number
    return [(f(), f()) for _ in r(count)]

严格来说,这与其他答案或多或少相同,但它做了两件对我来说看起来不错的事情。

首先,它通过将 random() - 0.5 放入 lambda 中来删除重复的代码。

其次,对于一定的大小范围,它选择使用xrange() 而不是range(),以免不必要地生成你要丢弃的巨大数字列表。您可能想调整确切的数字,因为我根本没有玩过它,我只是认为这可能是一个潜在的效率问题。

【讨论】:

  • 为什么不只是总是使用xrange?
  • 这是一个不错的选择。我假设只为两次迭代创建一个生成器可能比创建一个只有两个元素的列表更昂贵。当然,对于生成器和列表的昂贵程度,我没有基准,但不知何故,我有一种感觉,如果 xrange(2)range(2) 更有效,那么实施就会出现严重错误。
【解决方案5】:

在 PyDev 中应该有一种方法可以抑制代码分析错误,如下所示:

http://pydev.org/manual_adv_assistants.html

此外,PyDev 将忽略以下划线开头的未使用变量,如下所示:

http://pydev.org/manual_adv_code_analysis.html

【讨论】:

    【解决方案6】:

    试试这个:

    while count > 0:
        pattern.append((random() - 0.5, random() - 0.5))
        count -= 1
    

    【讨论】:

      【解决方案7】:
      import itertools, random   
      
      def RandomSample2D(npoints, get_random=lambda: random.uniform(-.5, .5)):
          return ((r(), r()) for r in itertools.repeat(get_random, npoints))
      
      • 明确使用random.uniform()
      • 返回一个迭代器而不是列表

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-06
        • 2017-08-17
        • 1970-01-01
        • 2019-07-19
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        相关资源
        最近更新 更多