Qual é a melhor maneira de obter o último item de um iterador no Python 2.6? Por exemplo, diga
my_iter = iter(range(5))
Qual é o caminho mais curto-code / mais limpa de obter 4
a partir de my_iter
?
Eu poderia fazer isso, mas não parece muito eficiente:
[x for x in my_iter][-1]
python
python-3.x
python-2.7
iterator
Peter
fonte
fonte
iter(range(5))
Respostas:
fonte
None
? É exatamente para isso queNone
serve. Você está sugerindo que algum valor padrão específico da função pode até estar correto? Se o iterador não iterar de fato, um valor fora da banda é mais significativo do que algum padrão enganoso específico de função.None
como valor padrão, é sua escolha. Nenhum nem sempre é o padrão mais sensato e pode nem estar fora da banda. Pessoalmente, tendo a usar 'defaultvalue = object ()' para ter certeza de que é um valor verdadeiramente único. Estou apenas indicando que a escolha do padrão está fora do escopo deste exemplo.None
como valor finalUse um
deque
de tamanho 1.fonte
Se você estiver usando Python 3.x:
se você estiver usando o python 2.7:
Nota:
Normalmente, a solução apresentada acima é o que você precisa para casos regulares, mas se você está lidando com uma grande quantidade de dados, é mais eficiente usar um
deque
tamanho 1. ( fonte )fonte
*lst, last = some_iterable
._
é uma variável especial em python e usada para armazenar o último valor ou para dizer que não me importo com o valor, então pode ser limpo.Provavelmente vale a pena usar
__reversed__
se estiver disponívelfonte
Tão simples quanto:
fonte
enumerate
retorna(index, value)
como:(0, val0), (1, val1), (2, val2)
... e então por padrãomax
quando dada uma lista de tuplas, compara apenas com o primeiro valor da tupla, a menos que os dois primeiros valores sejam iguais, o que eles nunca estão aqui porque eles representam índices. Então o subscrito final é porque max retorna a tupla inteira (idx, valor) enquanto estamos apenas interessados emvalue
. Idéia interessante.É improvável que seja mais rápido do que o loop for vazio devido ao lambda, mas talvez dê a outra pessoa uma ideia
Se o iter estiver vazio, um TypeError é gerado
fonte
TypeError
para um iterável vazio, você também pode fornecer um valor padrão por meio do valor inicial dereduce()
, por exemplolast = lambda iterable, default=None: reduce(lambda _, x: x, iterable, default)
,.Tem isso
Se a duração da iteração for verdadeiramente épica - tão longa que materializar a lista irá exaurir a memória - então você realmente precisa repensar o design.
fonte
eu usaria
reversed
, exceto que leva apenas sequências em vez de iteradores, o que parece bastante arbitrário.De qualquer maneira, você terá que percorrer todo o iterador. Com eficiência máxima, se você não precisar do iterador nunca mais, pode simplesmente destruir todos os valores:
Eu acho que esta é uma solução abaixo do ideal, no entanto.
fonte
A biblioteca toolz oferece uma boa solução:
Mas adicionar uma dependência não principal pode não valer a pena para usá-la apenas neste caso.
fonte
Veja este código para algo semelhante:
http://excamera.com/sphinx/article-islast.html
você pode usá-lo para pegar o último item com:
fonte
islast
em sua resposta (consulte meta.stackexchange.com/questions/8231/… ).Eu apenas usaria
next(reversed(myiter))
fonte
A questão é sobre como obter o último elemento de um iterador, mas se o seu iterador for criado aplicando condições a uma sequência, então reverso pode ser usado para encontrar o "primeiro" de uma sequência reversa, olhando apenas para os elementos necessários, aplicando reverter para a própria sequência.
Um exemplo inventado,
fonte
Como alternativa para iteradores infinitos, você pode usar:
Achei que seria mais lento,
deque
mas é tão rápido e, na verdade, mais rápido do que o método de loop (de alguma forma)fonte
A pergunta está errada e só pode levar a uma resposta complicada e ineficiente. Para obter um iterador, é claro que você começa a partir de algo que é iterável, que na maioria dos casos oferece uma maneira mais direta de acessar o último elemento.
Depois de criar um iterador a partir de um iterável, você fica preso em percorrer os elementos, porque essa é a única coisa que um iterável fornece.
Portanto, a maneira mais eficiente e clara não é criar o iterador em primeiro lugar, mas usar os métodos de acesso nativos do iterável.
fonte