12

我想知道是否有更好的方法在列表中一次迭代两个项目。我经常使用 Maya,它的一个命令 (listConnections) 返回一个交替值列表。该列表将类似于 [connectionDestination、connectionSource、connectionDestination、connectionSource]。要对这个列表做任何事情,理想情况下我想做类似的事情:

for destination, source in cmds.listConnections():
    print source, destination

当然,您可以使用 [::2] 迭代列表中的所有其他项目并枚举和源将是索引 + 1,但是您必须添加对奇数列表和内容的额外检查。

到目前为止,我想出的最接近的事情是:

from itertools import izip
connections = cmds.listConnections()
for destination, source in izip(connections[::2], connections[1::2]):
    print source, destination

这不是很重要,因为我已经有了做我想做的事的方法。这似乎是应该有更好的方法的事情之一。

4

2 回答 2

9

您可以使用以下方法对可迭代的项目进行分组,取自文档zip()

connections = cmds.listConnections()
for destination, source in zip(*[iter(connections)]*2):
    print source, destination

或者对于更易读的版本,使用itertools 文档中的 grouper配方

def grouper(n, iterable, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)
于 2012-07-05T18:33:24.450 回答
1

所有,很好的问题和答案。我想提供另一个解决方案来补充 Andrew Clark 的回答(使用 itertools 的道具!)。他的答案像这样返回每个值:

iterable = [0, 1, 2, 3, 4, 5, 6,...] n = 2 grouper(n, iterable, fillvalue=None) --> [(0, 1), (2, 3), (3, 4), (5, 6),...]

在下面的代码中,每个值将出现在 n 个子序列中。像这样:

def moving_window(n, iterable):
  start, stop = 0, n
  while stop <= len(iterable):
      yield iterable[start:stop]
      start += 1
      stop += 1

--> [(0, 1), (1, 2), (2, 3), (3, 4),...]

这种“移动窗口”或“内核”的常见应用是科学和金融中的移动平均线。

另请注意,yield 语句允许根据需要创建每个子序列,而不是将其存储在内存中。

于 2015-07-15T15:21:27.070 回答