Python for index从索引1开始或忽略第一个

时间:2019-01-25 07:08:53

标签: python python-3.x loops

我是Python的新手。我有以下代码:

>for e in entries:
     print(e)

但是如何忽略条目中的第一个元素?

我想从索引1而不是0进行迭代,并迭代到最后一个元素。

6 个答案:

答案 0 :(得分:4)

有几种方法可以做到这一点。

  1. for e in entries[1:]:
        print(e)
    
    此方法创建一个新列表,其中包含第一个元素entries的所有元素,然后对其进行迭代。它最清晰易读,但仅适用于list s(和tuple s),并且存在复制列表的所有问题。
  2. iterator = iter(entries)
    next(iterator)
    for e in iterator:
        print(e)
    
    此方法创建一个迭代器,丢弃第一个项目,然后对其进行迭代。这可能是最快的方法,但它并不是很容易阅读。
  3. for i, e in enumerate(entries):
        if i > 0:  # or, if i:
            print(e)
    
    这种方法根本不是很快,但是比第二种方法更易于阅读。它比第一个可能 *差,除非您出于某些原因确实不想复制该列表。
  4. import itertools
    ...
    for e in itertools.islice(entries, 1, None):
        print(e)
    
    这是2的版本,具有1的所有可读性优点。我想说这可能是最好的方法,但是使用1最安全,因为这是人们的期望。

*:在使用timeit.timeit(来自timeit模块的代码)测试代码之前,速度不应该成为问题

为了对此进行测试,我编写了一个骇人的测试套件:

import timeit

for i, setup in enumerate(("import itertools\nentries=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]", "import itertools\nentries=list(range(1000))", """import itertools
def primes():
    l = [2]
    for n in range(3,1000):
        for prime in l:
            if n % prime != 0:
                break
        else:
            yield n
            l.append(n)
entries=primes()""")):
    for j, stmt in enumerate(("""for e in entries[1:]:
    pass""", """iterator = iter(entries)
next(iterator)
for e in iterator:
    pass""", """for i, e in enumerate(entries):
    if i > 0:
        pass""", """for e in itertools.islice(entries, 1, None):
    pass""")):
        try:
            time = timeit.timeit(stmt=stmt, setup=setup)
        except:
            print(i, j, "DOES NOT WORK")
        else:
            print(i, j, time)

此输出:

0 0 0.7670026040000266
0 1 0.7781598509996002
0 2 1.794472709999809
0 3 0.9263826839996909
1 0 35.545838756000194
1 1 29.032120127000326
1 2 145.82462093200002
1 3 40.03643834500008
2 0 DOES NOT WORK
2 1 DOES NOT WORK
2 2 0.5132426549998854
2 3 0.490669440000147

与所有这些事情一样,结果并非我所期望的。这就是为什么您从不进行优化,然后再对其进行测试!

用于少量输入

对于较小的输入([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),第一种方法(slice)最快。这是因为创建更少的字节码(基本上是更少的代码)可以节省创建另一个列表的成本。由于效率高,紧随其后的是第二种方法(next,然后是第三种方法(enumerate),因为它有一个额外的嵌套迭代器。最后也是最不重要的一点是第四种方法(islice),因为它有一个额外的嵌套迭代器,可以执行非平凡的功能(模拟切片)。

用于大输入

对于较大的输入(list(range(1000))),next最快(由于优化),其次是slice,之后是islice。然后我睡着了。然后最终 enumerate完成。这可能是因为列表比256长,所以Python必须为enumerate创建新的整数对象才能对其进行编号。 It's a long story.

用于发电机输入

对于生成器输入(primes()),slice不起作用。 但是,我的测试代码是错误的,导致next在不应该出现的时候出错,所以我不能告诉你哪个是最快的。抱歉!

但这可能是最好的,因为timeit.timeit运行1000000次迭代,并且我的主要计算器功能运行缓慢,以至于我一生都无法完成。

一切顺利,对吧?

答案 1 :(得分:2)

要进行迭代:

entries = iter(entries)
next(entries)
for e in entries:

不是所有可迭代的,而是所有序列的。

for e in entries[1:]

答案 2 :(得分:0)

您需要了解为此的索引编制

您可以从列表中获取特定元素,例如使用6索引的元素:

entries = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
entries[6]
>> 6

还有切片功能,可以检索给定范围(例如从索引1到索引7)的元素

entries[1:8] # syntax-> [starting index: ending_index+1]

>> [1, 2, 3, 4, 5, 6, 7]

但是您要从索引1返回到结尾,因此可以使用:

entries[1:]
>> [1, 2, 3, 4, 5, 6, 7, 8, 9]

如果冒号(:)之后没有数字,则所有元素都将在起始索引之后返回

所以您应该:

for e in entries[1:]:
     print(e)

答案 3 :(得分:0)

有多种方法跳过entries的第一个索引。

示例1:使用range()函数跳过索引。

从本质上讲,我们采用条目的长度,并以1开始,并以该长度结束。然后,我们使用i引用每个索引。

for i in range(1, len(entries)):
    print(entries[i])

示例2:更改列表。

您可以更改要遍历的列表的内容。

for e in entries[1:]:
    print(e)

答案 4 :(得分:0)

entries = 'ABCD'

for e in entries[1:]:
     print(e)

B
C
D

答案 5 :(得分:0)

from operator import itemgetter

l = 'ABCD'

for i in itemgetter(slice(1,None))(l):
    print(i)

# B
# C
# D