不使用循环索引写for循环的Pythonic方式

8

以下代码涉及到IT技术,使用for循环生成一系列随机偏移量,以在程序的其他地方使用。

这个for循环的索引未被使用,导致Eclipse / PyDev将其标记为警告的“有问题”代码。

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

    return pattern

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

有人有什么建议吗?


2
请参见https://dev59.com/KXRA5IYBdhLWcg3wzhVY。 - Nicholas Knight
7个回答

18

2
PyDev 抑制未使用变量的警告,如果它们以下划线开头,则 _i 也可以。 - Craig McQueen
您也可以添加“i = i”。这样做的好处是,它可以在任何开发环境中工作,而不受内置变量忽略的影响。 - Matthew Wilcoxson

5

那么 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)]

1
作为一个函数:fn = lambda count: itertools.repeat(lambda: (random() - 0.5, random() - 0.5), count) - Chris Lutz

4
randomSample = [(random() - 0.5, random() - 0.5) for _ in range(count)]

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

[(-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)]
>>> 

你可以理解为...


2
这只是将未使用的变量重命名为_,所以并没有真正改进,除非Eclipse特别忽略它。 - McPherrinM
3
“_”是一个虚拟变量,Eclipse不应该报错,但我不确定,因为我从未在该平台上开发Python。祝好运,请告诉我它是否会出错。 - Escualo
@WaffleMatt:请参考此处的帖子,其中解释了PyDev中的默认虚拟变量。 - Escualo
如果你无论如何都要给函数命名,为什么要使用lambda?def f(count) : return [(random() - 0.5, random() - 0.5) for _ in range(count)]` 明显更符合Python的风格。此外,如果我们讨论的是Python 2,这可能是生成器表达式(和xrange)的一个很好的候选。 - Parker Coates
谁在Python中接受下划线作为“表示未使用的循环索引的方式”?下划线已经在Python代码中频繁用于gettext,更不用说在REPL中的最后一个语句返回值了。 - Jeffrey Harris
显示剩余5条评论

2
晚了一步,但这里有一个潜在的想法:
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)]

严格来说,这与其他答案大致相同,但它做了两件看起来很好的事情。
首先,通过将其放入lambda中,它删除了您从两次写入random() - 0.5中具有的重复代码。
其次,对于某个大小范围,它选择使用xrange()而不是range(),以避免不必要地生成一个你将要丢弃的巨大数字列表。您可能需要调整确切的数字,因为我根本没有尝试过它,我只是认为它可能是一个潜在的效率问题。

1
为什么不总是使用xrange? - Alice Purcell
这是一个不错的替代方案。我假设仅为两个迭代创建生成器可能比仅创建两个元素的列表更昂贵。当然,我没有关于生成器和列表可能或可能不可能昂贵的基准,但我有一种感觉,如果 xrange(2)range(2) 更有效,则实现存在严重问题。 - Chris Lutz

1

0

试试这个:

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

0
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()
  • 返回迭代器而非列表

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接