【问题标题】:"Pythonic" for loop over integers 0 to k-1 except i“Pythonic” for 循环整数 0 到 k-1,除了 i
【发布时间】:2014-08-20 21:51:16
【问题描述】:

我想创建一个 for 循环,它将遍历整数 0 到 k-1,但整数 i 除外。 (我正在比较一些 k 个项目的列表,我不需要将一个列表中的项目 i 与另一个列表中的项目 i 进行比较。)

我有一种相当简单的方法,但我一直认为还有一种更“Pythonic”、更优雅的方法。

我正在做的是:

tocheck = range(k)
del(tocheck[i])
for j in tocheck:

这很简单,但我喜欢 Python 的一件事是,对于这样的事情,似乎总有一个聪明的“Pythonic”技巧。

谢谢。

【问题讨论】:

  • 您能否再解释一下整体问题?比如你对这两个列表做了什么?
  • 据我了解,在这个问题中基于意见的是 pythonic 的概念,因为它基本上要求一个简单任务的 pythonic 版本。如果这个问题主要被认为是基于意见的,那么 SO-question 的全部股份要求 pythonic - 或一般地道的 - 做事方式也应该被视为,我想知道我们是否真的想这样做。跨度>
  • 我认为这个问题可以用 Python 社区普遍认为优越的替代方案来回答这个问题,而无需深入研究哪个是 Pythonic的更多基于意见的问题.
  • 这个问题是discussed on Meta

标签: python loops for-loop


【解决方案1】:

也许使用itertools.chain

from itertools import chain

for j in chain(range(i), range(i+1, k)):
    # ...

【讨论】:

  • 似乎比使用 continue 循环更快(至少对于 k=1000 的测试
  • +1 我喜欢它避免在每次迭代中测试j 的值,尽管对于任何非平凡的循环体,性能增益可能是最小的。
【解决方案2】:

我认为留下空白最惯用的方法是使用 continue 跳过 for 循环。

i = 20
for j in range(50):
    if j==i:
        continue
    print j

【讨论】:

  • 我也最喜欢那个,它还为您提供了一个自然的地方来放置评论,解释为什么我需要被跳过。
【解决方案3】:

我想我会做以下之一:

for j in range(k):
    if j == i: continue
    ...code here...

或(固定)

tocheck = range(k)
for j in tocheck[:i] + tocheck[i + 1:]:
    ...code here...

for j in range(i) + range(i + 1, k):
    ...code here...

【讨论】:

  • 第二种写法很复杂for j in []。并且range 对象没有定义__add__,所以第三个只能在旧的 2.x 版本中工作,它会非常慢。
  • 第二个例子不会产生正确的输出。它总是空的。
  • 你们当然是对的,不知道我在想什么,估计该睡觉了……
【解决方案4】:

这个怎么样:

for l in (j  for j in range(k) if j != i):
    ....

这使用了一个生成器表达式,可能被认为是“pythonic”,尽管表达式本身有点混乱,可能被认为是不优雅的。

【讨论】:

    【解决方案5】:

    另一种可能性是仅使用迭代器:

    from itertools import chain
    k = 10
    l = range(k)
    i = 2
    
    print [el for el in iter(l[:i])] + [el for el in iter(l[i+1:])]
    

    这适用于任何列表l。如果l 只是一些range,您可以省略l 的显式定义并简单地写:

    print [el for el in xrange(i)] + [el for el in xrange(i+1,k)]
    

    【讨论】:

    • 无需在列表中显式调用iter。列表推导等同于将 chain 迭代器传递给 list。这与 FatalError 发布的答案相同。
    • @chepner:啊,当然,你是对的!傻我。我最初想建议内置的 iter 方法,因为它允许在不像范围那么微不足道的列表上获取迭代器,但 chain 迭代器确实使答案毫无意义。虽然仍然可以将它与浅拷贝一起使用,但会改变答案。
    猜你喜欢
    • 2016-03-18
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 2019-11-21
    • 2018-01-11
    • 2011-06-14
    相关资源
    最近更新 更多