【问题标题】:Python range len vs enumeratePython 范围 len 与枚举
【发布时间】:2018-08-06 23:28:59
【问题描述】:

我从range(len(list)) or enumerate(list)? 读到,使用range(len(s)) 不是编写Python 的好方法。如果我们不需要循环 len(s) 次而是例如 len(s)//3 次或 len(s)-5 次,那么如何以另一种方式编写 for 循环?是否可以将这些循环转换为使用enumerate

例如,我有一个项目,我有一个包含 3n 个元素的列表 's[0], s[1],...,s[3n-1]' 我需要在 nx3 表中打印它们.我写了类似的代码

for i in range(len(s)//3):
    row = str(s[3*i]) + " " + str(s[3*i+1]) + " " + str(s[3*i+2])
    print(row)

【问题讨论】:

  • 你能举一个更具体的例子来说明你想要做什么吗?
  • 不完全重复,因为这个问题还询问关于迭代列表的部分
  • “使用 range(len(s)) 不是编写 Python 的好方法”不确定您从那个问题或其他问题中得到这个想法的地方。 Python 完全没问题。不建议的是迭代索引,然后在循环中获取元素;那么enumerate 是首选。
  • @user2219896 是的,所以关键是您通常不想在要迭代 元素时使用 range(len(l))一个列表(尽管可能仍然存在有意义的情况)。但是如果你只想遍历一个数字序列,不管是len(l)还是其他任何数字,都是正确的做法(事实上,这正是range/xrange的目的)。在这种情况下,Imo 使用 enumerate 并忽略列表元素是不必要的,最重要的是,您使用列表元素这一事实稍微不那么明确。

标签: python python-3.x


【解决方案1】:

使用 itertools 的解决方案,

import itertools

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

s = list(range(10))

for row in list(grouper(s, 3)):
    print(row)

给予

(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9, None, None)

[Program finished]

其他想法


# if you're printing it straight away, you might as well
print(*s[3*i: 3*i+3], sep=' ')

for i in range(0, len(s), 3):
    print(' '.join(s[i:i + 3])

# so you can kind of cheat with numpy for this:

for row in numpy.array(s).reshape((3,-1)):
     print(row)

【讨论】:

    【解决方案2】:

    你想通过某种滑动窗口浏览你的收藏。在这种情况下,我建议使用itertools.islice

    >>> from itertools import islice
    >>> 
    >>> s = [i for i in range(10)] # Or whatever iterable you have
    >>> 
    >>> iter1 = islice(s, 1, None)
    >>> iter2 = islice(s, 2, None)
    >>> 
    >>> for a, b, c in zip(s, iter1, iter2):
    ...     print('[{}, {}, {}]'.format(a, b, c))
    ... 
    [0, 1, 2]
    [1, 2, 3]
    [2, 3, 4]
    [3, 4, 5]
    [4, 5, 6]
    [5, 6, 7]
    [6, 7, 8]
    [7, 8, 9]
    

    如果您不介意制作数据副本,可以使用传统的切片表示法:

    >>> s = [i for i in range(10)] # Again, this could be any iterable
    >>> 
    >>> for a, b, c in zip(s, s[1:], s[2:]):
    ...     print('[{}, {}, {}]'.format(a, b, c))
    ... 
    [0, 1, 2]
    [1, 2, 3]
    [2, 3, 4]
    [3, 4, 5]
    [4, 5, 6]
    [5, 6, 7]
    [6, 7, 8]
    [7, 8, 9]
    

    【讨论】:

      【解决方案3】:

      如果您要遍历整个列表:

      for x in lst:
          print(x)
      

      如果您要遍历整个列表,但只需要索引:

      for i, _ in enumerate(lst):
          print(i)
      

      如果您要遍历整个列表,但不需要索引或数据:

      for _ in lst:
          print("hello")
      

      如果您正在迭代列表的一部分:

      for x in lst[:-5]:
          print(x)
      

      等等。

      我不确定您为什么要遍历列表的 part,这似乎很奇怪。我很想听听您的用例,因为它可能会得到改进。

      查看您现在发布的代码,@Metareven 有一个很好的解决方案 - 以您想要处理的大小对列表进行迭代。

      【讨论】:

        【解决方案4】:

        您的代码看起来还不错,但是如果您想一次迭代 3 个元素,我会创建一个 for 循环,将 i 变量增加 3 而不是 1,如下所示:

        for i in range(0,len(s),3):
          row = str(s[i]) + " " + str(s[i+1]) + " " + str(s[i+2])
          print(row)
        

        【讨论】:

          猜你喜欢
          • 2012-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多