Pergunta

Como pode uma iteração através de uma sequência não-vazia, sem filtragem e nenhuma agregação (sum(), etc), rendimento nada?

Considere um exemplo simples:

sequence = ['a', 'b', 'c']
list((el, ord(el)) for el in sequence)

Esta [('a', 97), ('b', 98), ('c', 99)] rendimentos como esperado.

Agora, basta trocar o ord(el) fora para uma expressão que dá o primeiro valor de algum gerador usando (...).next() - perdoar o exemplo artificial:

def odd_integers_up_to_length(str):
    return (x for x in xrange(len(str)) if x%2==1)

list((el, odd_integers_up_to_length(el).next()) for el in sequence)

Este rendimentos []. Sim, lista vazia. Sem ('a',stuff) tuplas. Nada.

Mas não estamos filtrando ou agregar ou reduzir. Um gerador de expressão sobre objectos n sem filtragem ou agregação deve produzir objectos n, direita? O que está acontecendo?

Foi útil?

Solução

odd_integers_up_to_length(el).next() elevará StopIteration, que não está preso lá, mas é capturado para a expressão gerador de dentro dele, parando-o sem nunca ceder nada.

olhada na primeira iteração, quando o valor é 'a':

>>> odd_integers_up_to_length('a').next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Outras dicas

O que acontece é que a chamada next() gera uma exceção StopIteration, que borbulha a pilha para a expressão gerador externo e pára que iteração.

A StopIteration é o caminho normal para um iterador para sinal de que ele é feito. Geralmente nós não vê-lo, porque geralmente a chamada next() ocorre dentro de uma construção que consome o iterador, por exemplo, for x in iterator ou sum(iterator). Mas quando chamamos next() diretamente, somos os responsáveis ??por pegar o StopIteration. Não fazê-lo um vazamento na abstração, que aqui leva a um comportamento inesperado na iteração externa.

A lição, suponho:. Ter cuidado com chamadas diretas para next()

str é uma palavra-chave reservada, você deve nomear sua variável diferente

Eu também estava a aconselhar sobre a próxima

>>> seq=['a','b','c']
>>> list((el,4) for el in seq)
[('a',4), ('b',4), ('c',4)]

Portanto, não é list dando-lhe problemas aqui ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top