Posso fazer minha pergunta melhor apenas dando um exemplo. Digamos que eu queira usar uma compreensão de lista para gerar um conjunto de tuplas de 3 elementos a partir de dois loops, algo assim:
[ (y+z,y,z) for y in range(10) if y%2==0 for z in range(20) if z%3==0 ]
Isso funciona, me dando
[(0, 0, 0), (3, 0, 3), (6, 0, 6), (9, 0, 9), (12, 0, 12), (15, 0, 15), ... ]
Estou pensando, porém, se há uma maneira de fazer isso de forma mais limpa, algo como
[ (x,y,z) for y in range(10) if y%2==0 for z in range(20) if z%3==0 ... somehow defining x(y,z) ... ]
Eu consideraria algo assim mais limpo, especialmente porque o que eu realmente preciso fazer é muito mais complicado do que o exemplo que dou aqui. Tudo o que tentei me deu um erro de sintaxe.
Você pode fazer:
Isso foi otimizado desde o Python 3.9: https://docs.python.org/3/whatsnew/3.9.html#optimizations
Eu pularia a divisão e apenas geraria os múltiplos desejados explicitamente.
Agora você pode usar
itertools.product
em vez de dois geradores.Não há razão para fazer isso no cenário descrito, não importa quão complexa seja a expressão que está sendo nomeada. Se a expressão for complicada, apenas divida a
tuple
definição:Se você realmente testar e produzir o valor (então ele deve ser atribuído a um nome), claro, use a solução de Andrej e faça:
ou se você não se importa com
x
vazamentos do escopo do listcomp, a:=
abordagem ainda mais simples/concisa baseada em walrus ( ):Mas quando você só precisa do valor uma vez, não há muito a ganhar em nomeá-lo, a menos que você tenha um nome realmente bom para dar a ele para maior clareza (e eu diria que definir uma tupla nomeada simples para os valores produzidos pode ser o caminho a seguir nesse caso, em vez de apenas dar a ele um nome útil dentro do listcomp).
Se a expressão for complexa o suficiente para justificar mais do que isso, ela será complexa o suficiente para que você provavelmente deva simplesmente descartar o listcomp em favor de uma expansão manual dele para um loop for, por exemplo:
ou fatorando-o em uma função geradora:
que você pode invocar com
do_whatever()
(list(do_whatever())
para coletar os resultados imediatamentelist
se você não puder simplesmente iterá-los um por um para processamento).