简体   繁体   English

Python 范围 len 与枚举

[英]Python range len vs enumerate

I read from range(len(list)) or enumerate(list)?我从范围(len(列表))或枚举(列表)读取? that using range(len(s)) is not very good way to write Python.使用range(len(s))并不是编写 Python 的好方法。 How one can write for loops in alternative way if we do not need to loop len(s) times but for example len(s)//3 times or len(s)-5 times?如果我们不需要循环len(s)次但例如len(s)//3次或len(s)-5次,如何以另一种方式编写 for 循环? Is it possible to convert those loops to use enumerate ?是否可以将这些循环转换为使用enumerate

For example, I had a project where I had a list of 3n elements 's[0], s[1],...,s[3n-1]' and I needed to print them in a nx3 table.例如,我有一个项目,其中有一个包含 3n 个元素“s[0]、s[1]、...、s[3n-1]”的列表,我需要将它们打印在 nx3 表中。 I wrote the code something like我写了类似的代码

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

If you're iterating over an entire list:如果您遍历整个列表:

for x in lst:
    print(x)

If you're iterating over an entire list, but you only need the index:如果你遍历整个列表,但你只需要索引:

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

If you're iterating over an entire list, but you don't need the index or the data:如果您遍历整个列表,但不需要索引或数据:

for _ in lst:
    print("hello")

If you're iterating over part of a list:如果您要遍历列表的一部分:

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

And so on.等等。

I'm not sure why you want to iterate over part of a list though, that seems strange.我不确定为什么要遍历列表的一部分,这看起来很奇怪。 I'd be interested to hear your use case, as it could probably be improved.我很想听听您的用例,因为它可能会得到改进。

Looking over the code you've now posted, @Metareven has a good solution - iterating over the list in chunks of the size you want to process.查看您现在发布的代码,@Metareven 有一个很好的解决方案 - 以您要处理的大小的块迭代列表。

Your code doesn't look that bad, but if you want to iterate over 3 elements at a time I would make a for loop that increments the i variable by 3 instead of one, like so:您的代码看起来还不错,但是如果您想一次迭代 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)

It seams you want to go through your collection with some sort of sliding window.它接缝您想通过某种滑动窗口浏览您的收藏。 In that case, I would suggest using itertools.islice .在这种情况下,我建议使用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]

If you don't mind making copies of your data, you could use the traditional slicing notation:如果您不介意复制数据,您可以使用传统的切片表示法:

>>> 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]

Solution using itertools,使用 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)

gives

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

[Program finished]

Other ideas其他想法


# 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM