【问题标题】:More Pythonic Way to Run a Process X Times运行 X 次进程的更多 Pythonic 方式
【发布时间】:2011-05-14 23:00:41
【问题描述】:

哪个更pythonic?

While循环:

count = 0
while count < 50:
    print "Some thing"
    count = count + 1

For循环:

for i in range(50):
    print "Some thing"

编辑:不重复,因为这有答案来确定哪个更清晰,而不是如何在没有 'i' 的情况下运行范围 - 即使最终是最优雅的

【问题讨论】:

标签: python loops


【解决方案1】:

个人:

for _ in range(50):
    print "Some thing"

如果您不需要i。如果您使用 Python xrange,因为无需事先生成整个列表。

【讨论】:

  • 注意 _ 被映射到 gettext 翻译函数。
  • 感谢您的回答;这是我没有使用 for 循环的主要原因,因为“i”中有一个未使用的变量。
  • _ 就像任何其他变量一样。只有在 REPL 中它才具有特殊意义。 OP也可以坚持i
  • @vezult 我喜欢这个,因为它清楚地表明该变量没有在语句中使用。是否有理由掩盖这一点,坚持使用i
  • 我坚信添加小马,尤其是当它听起来合适时......对于范围内的小马(50):print(“neigh”)#python 3
【解决方案2】:

for 循环肯定更符合 Python 风格,因为它使用 Python 更高级别的内置功能来更清晰、更简洁地传达您正在执行的操作。 range 与 xrange 的开销以及分配未使用的 i 变量源于缺少像 Verilog 的 repeat 语句这样的语句。坚持 for range 解决方案的主要原因是其他方式更复杂。例如:

from itertools import repeat

for unused in repeat(None, 10):
    del unused   # redundant and inefficient, the name is clear enough
    print "This is run 10 times"

在这里使用重复而不是范围不太清楚,因为它不是众所周知的函数,而且更复杂,因为您需要导入它。如果您需要参考,主要的风格指南是 PEP 20 - The Zen of PythonPEP 8 - Style Guide for Python Code

我们还注意到 for range 版本是在 language referencetutorial 中使用的明确示例,尽管在这种情况下使用了值。这确实意味着这种形式肯定比 C 风格 for 循环的 while 扩展更熟悉。

【讨论】:

  • 直接使用重复的东西不是更好吗,即:for s in repeat('This is run 10 times', 10): print s??
  • 当然!但是示例代码中的打印只是重复代码部分的示例,可能没有中心对象。
  • Python 核心开发者说这比使用range()twitter.com/raymondh/status/1144527183341375488 更快
  • 确实更快,因为它不需要为每次迭代查找或创建不同的int 对象。但是,程序员的时间可能比执行时间更有价值。
【解决方案3】:

如果您关注循环中发生的副作用,我个人会选择range() 方法。

如果你关心你在循环中调用的任何函数的结果,我会选择列表理解或map 方法。像这样的:

def f(n):
    return n * n

results = [f(i) for i in range(50)]
# or using map:
results = map(f, range(50))

【讨论】:

  • results = (f for i in range(50))
  • 结果 = itertools.imap(f, range(50))
  • @ralu,但前提是您不需要重复或随机访问结果。
  • result = tuple(results) 并且比列表快得多,因为在元组上切片是 O(1)
【解决方案4】:

怎么样?

while BoolIter(N, default=True, falseIndex=N-1):
    print 'some thing'

或者以更丑陋的方式:

for _ in BoolIter(N):
    print 'doing somthing'

或者如果你想通过最后一次赶上:

for lastIteration in BoolIter(N, default=False, trueIndex=N-1):
    if not lastIteration:
        print 'still going'
    else:
        print 'last time'

地点:

class BoolIter(object):

    def __init__(self, n, default=False, falseIndex=None, trueIndex=None, falseIndexes=[], trueIndexes=[], emitObject=False):
        self.n = n
        self.i = None
        self._default = default
        self._falseIndexes=set(falseIndexes)
        self._trueIndexes=set(trueIndexes)
        if falseIndex is not None:
            self._falseIndexes.add(falseIndex)
        if trueIndex is not None:
            self._trueIndexes.add(trueIndex)
        self._emitObject = emitObject


    def __iter__(self):
        return self

    def next(self):
        if self.i is None:
            self.i = 0
        else:
            self.i += 1
        if self.i == self.n:
            raise StopIteration
        if self._emitObject:
            return self
        else:
            return self.__nonzero__()

    def __nonzero__(self):
        i = self.i
        if i in self._trueIndexes:
            return True
        if i in self._falseIndexes:
            return False
        return self._default

    def __bool__(self):
        return self.__nonzero__()

【讨论】:

    【解决方案5】:

    没有一种真正的 Pythonic 方式来重复某些内容。 但是,这是一个更好的方法:

    map(lambda index:do_something(), xrange(10))
    

    如果需要传递索引则:

    map(lambda index:do_something(index), xrange(10))
    

    考虑将结果作为集合返回。 因此,如果您需要收集结果,它可以提供帮助。

    【讨论】:

    • 这不仅不是更好(函数调用开销、鲜为人知的 lambda 表达式、在列表中收集未使用的结果),10 也不是可迭代的。
    • 是的,xrange(10) 不是 10。我说它更好,因为您不需要编写函数或创建循环。但是,正如我所说,没有真正的 Pythonic 方式。我更改了代码,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2017-11-24
    • 2016-02-09
    • 2014-02-05
    • 2022-08-03
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多