代码之家  ›  专栏  ›  技术社区  ›  Peter

从Python迭代器获取最后一项的最干净方法

  •  86
  • Peter  · 技术社区  · 15 年前

    my_iter = iter(range(5))
    

    最短的代码/最干净的获取方式是什么 4 从…起 my_iter

    我可以这样做,但似乎效率不高:

    [x for x in my_iter][-1]
    
    12 回复  |  直到 7 年前
        1
  •  116
  •   Thomas Wouters    15 年前
    item = defaultvalue
    for item in my_iter:
        pass
    
        2
  •  97
  •   Eric O. Lebigot    4 年前

    如果您使用的是Python 3.x:

    *_, last = iterator # for a better understanding check PEP 448
    print(last)
    

    如果您使用的是python 2.7:

    last = next(iterator)
    for last in iterator:
        continue
    print last
    


    旁注:

    deque 一号的( source )

    from collections import deque
    
    #aa is an interator
    aa = iter('apple')
    
    dd = deque(aa, maxlen=1)
    last_element = dd.pop()
    
        3
  •  76
  •   Cristian Ciupitu    9 年前

    deque 一号的。

    from collections import deque
    
    #aa is an interator
    aa = iter('apple')
    
    dd = deque(aa, maxlen=1)
    last_element = dd.pop()
    
        4
  •  35
  •   John La Rooy    15 年前

    __reversed__ 如果可以的话

    if hasattr(my_iter,'__reversed__'):
        last = next(reversed(my_iter))
    else:
        for last in my_iter:
            pass
    
        5
  •  30
  •   Chema Cortes    13 年前

    简单到:

    max(enumerate(the_iter))[1]
    
        6
  •  23
  •   John La Rooy    15 年前

    由于lambda的原因,这不太可能比空for循环快,但可能会给其他人一个想法

    reduce(lambda x,y:y,my_iter)
    

    如果iter为空,则会引发TypeError

        7
  •  10
  •   S.Lott    15 年前

    有这个

    list( the_iter )[-1]
    

    如果迭代的长度真的很长——如此之长以至于具体化列表将耗尽内存——那么您确实需要重新考虑设计。

        8
  •  6
  •   Chris Lutz    15 年前

    我会用 reversed ,只是它只接受序列而不是迭代器,这似乎是任意的。

    无论如何,都必须运行整个迭代器。以最大效率,如果您不再需要迭代器,您可以丢弃所有值:

    for last in my_iter:
        pass
    # last is now the last item
    

    不过,我认为这是一个次优的解决方案。

        9
  •  4
  •   lumbric    6 年前

    toolz 库提供了一个很好的解决方案:

    from toolz.itertoolz import last
    last(values)
    

    但是仅仅在这种情况下使用非核心依赖项可能不值得。

        10
  •  1
  •   James Bowman    14 年前

    有关类似的内容,请参见此代码:

    http://excamera.com/sphinx/article-islast.html

    您可以使用它拾取最后一个项目:

    [(last, e) for (last, e) in islast(the_iter) if last]
    
        11
  •  0
  •   serv-inc    7 年前

    next(reversed(myiter))

        12
  •  0
  •   Wyrmwood    5 年前

    问题在于获取迭代器的最后一个元素,但是如果迭代器是通过对序列应用条件创建的,那么reversed可以用于查找反转序列的“第一个”,只查看所需的元素,方法是对序列本身应用reverse。

    一个人为的例子,

    >>> seq = list(range(10))
    >>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
    >>> last_even
    8
    
        13
  •  0
  •   qocu    5 年前

    from itertools import islice 
    last = list(islice(iterator(), 1000))[-1] # where 1000 is number of samples 
    

    deque 但它和for循环方法一样快,而且实际上比for循环方法快(不知何故)

        14
  •  -7
  •   ludwig    14 年前

    这个问题是错误的,只能导致一个复杂而低效的答案。 为了得到一个迭代器,您当然要从可iterable开始,在大多数情况下,这将提供一种更直接的方式来访问最后一个元素。

    因此,最有效和清晰的方法不是首先创建迭代器,而是使用iterable的本机访问方法。