AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 78975956
Accepted
bob.sacamento
bob.sacamento
Asked: 2024-09-12 07:08:29 +0800 CST2024-09-12 07:08:29 +0800 CST 2024-09-12 07:08:29 +0800 CST

compreensão de lista em python -- dois loops com três resultados?

  • 772

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.

python
  • 3 3 respostas
  • 84 Views

3 respostas

  • Voted
  1. Best Answer
    Andrej Kesely
    2024-09-12T07:17:27+08:002024-09-12T07:17:27+08:00

    Você pode fazer:

    out = [
        (x, y, z)
        for y in range(10)
        if y % 2 == 0
        for z in range(20)
        if z % 3 == 0
        for x in [y + z]  # <-- initialize `x` in list-comprehension
    ]
    

    Isso foi otimizado desde o Python 3.9: https://docs.python.org/3/whatsnew/3.9.html#optimizations

    • 5
  2. chepner
    2024-09-12T09:53:11+08:002024-09-12T09:53:11+08:00

    Eu pularia a divisão e apenas geraria os múltiplos desejados explicitamente.

    [(y+z,y,z) for y in range(0, 10, 2) for z in range(0, 20, 3)]
    

    Agora você pode usar itertools.productem vez de dois geradores.

    [(sum(p), *p) for p in product(range(0, 10, 2), range(0, 20, 3))]
    
    • 1
  3. ShadowRanger
    2024-09-13T06:52:06+08:002024-09-13T06:52:06+08:00

    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 tupledefinição:

    [(y+z,  # Doesn't matter if this is complex; by using one element per line, it's clear
            # the complexity doesn't interfere with interpreting the rest of the listcomp
      y,
      z)
     for y in range(10)
     if y%2==0
     for z in range(20) 
     if z%3==0]
    

    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:

    [(x, y, z)       # Produce here, having computed x only once
     for y in range(10)
     if y%2==0
     for z in range(20) 
     if z%3==0
     for x in [y+z]  # Substitute complex expression here
     if x%5==0       # Test here
    ]
    

    ou se você não se importa com xvazamentos do escopo do listcomp, a :=abordagem ainda mais simples/concisa baseada em walrus ( ):

    [(x, y, z)       # Produce here, having computed x only once
     for y in range(10)
     if y%2==0
     for z in range(20) 
     if z%3==0 and (x := y+z)%5==0  # Test and assign to x here
    ]
    

    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:

    result = []
    for y in range(10):
        if y%2 == 0:
            for z in range(20):
                if z%3 == 0:
                    x = y + z  # You can do the complex expression here, possibly breaking it up
                               # into multiple lines itself for clarity
                    result.append((x, y, z))
    

    ou fatorando-o em uma função geradora:

    def do_whatever():
        for y in range(10):
            if y%2 == 0:
                for z in range(20):
                    if z%3 == 0:
                        x = y + z  # You can do the complex expression here, possibly breaking it up
                                   # into multiple lines itself for clarity
                        yield (x, y, z)
    

    que você pode invocar com do_whatever()( list(do_whatever())para coletar os resultados imediatamente listse você não puder simplesmente iterá-los um por um para processamento).

    • 0

relate perguntas

  • Como divido o loop for em 3 quadros de dados individuais?

  • Como verificar se todas as colunas flutuantes em um Pandas DataFrame são aproximadamente iguais ou próximas

  • Como funciona o "load_dataset", já que não está detectando arquivos de exemplo?

  • Por que a comparação de string pandas.eval() retorna False

  • Python tkinter/ ttkboostrap dateentry não funciona quando no estado somente leitura

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve