Pergunta

O mapa () percorrer a lista como "para" faria? Existe um valor em usar mapa vs para?

Se assim for, agora minha aparência código como este:

for item in items:
    item.my_func()

Se isso faz sentido, eu gostaria de fazê-lo do mapa (). Isso é possível? O que é um exemplo como?

Foi útil?

Solução

Você pode usar map vez do for loop que você' ve mostrado, mas desde que você não parecem usar o resultado de item.my_func(), este é não é recomendado . map deve ser usado se você deseja aplicar uma função sem efeitos colaterais para todos os elementos de uma lista. Em todas as outras situações, use um explícita para-loop.

Além disso, a partir de Python 3.0 map retorna um gerador, então, nesse caso, map não se comportam da mesma (a menos que você avaliar explicitamente todos os elementos retornados pelo gerador, por exemplo, chamando list nele).


Editar : kibibu pergunta nos comentários para um esclarecimento sobre o motivo primeiro argumento do map deve não ser uma função com efeitos colaterais. Eu vou dar resposta a esta questão um tiro:

map se destina a ser passada uma função f no sentido matemática . Sob tais circunstâncias, não importa em que f ordem é aplicada aos elementos do segundo argumento (contanto que eles são retornou em sua ordem original, é claro). Mais importante, nessas circunstâncias map(g, map(f, l)) é semanticamente equivalente a map(lambda x: g(f(x)), l), , independentemente da ordem em que f e g são aplicadas a seus respectivos insumos .

por exemplo., Não importa se map retornos e iterator ou uma lista completa de uma só vez. No entanto, se f e / ou causar g efeitos colaterais, então essa equivalência só é garantida se a semântica da map(g, map(f, l)) são tais que a qualquer g estágio é aplicado à primeira n elementos retornados por map(f, l) antes map(f, l) aplica f para o elemento (n + 1) r de l. (O que significa que map deve executar o mais preguiçoso iteração possível --- que ele faz em Python 3, mas não em Python 2!)

Indo um passo além: mesmo se assumirmos a implementação Python 3 de map, a equivalência semântica pode facilmente quebrar se a saída de map(f, l) é exemplo passados ??através de itertools.tee antes de ser fornecido para a chamada map exterior.

A discussão acima pode parecer de natureza teórica, mas como os programas se tornam mais complexas, eles se tornam mais difícil raciocinar sobre e, portanto, mais difícil de depuração. Garantir que algumas coisas são alivia invariantes esse problema um pouco, e pode de fato impedem toda uma classe de bugs.

Por fim, map lembra muitas pessoas do seu homólogo verdadeiramente funcional em vários (puramente) linguagens funcionais. Passando-a "função" com efeitos colaterais irá confundir as pessoas. Portanto, visto que a alternativa (isto é, utilizando um ciclo explícita) não mais difícil é para implementar do que uma chamada para map, é altamente recomendável que um restringe o uso de map para aqueles casos em que a função a ser aplicada não causa efeitos colaterais .

Outras dicas

Você pode escrever isso usando mapa como este:

map(cls.my_func, items)

substituindo cls com a classe dos itens que você está interagindo sobre.

Como mencionado por Stephan202, este é não é recomendado , neste caso.

Como regra geral, se você quiser criar uma nova lista, aplicando alguma função para cada item na lista, mapa de uso. Isto tem o significado implícito que a função não tem efeito colateral, e, assim, você poderia (potencialmente) executar o mapa em paralelo.

Se você não deseja criar uma nova lista, ou se a função tem efeitos colaterais, use um loop for. Este é o caso no seu exemplo.

Há uma ligeira diferença semântica, o que provavelmente está fechado em especificação linguagem Python. O Mapa é explicitamente paralelizável, enquanto para apenas em situações especiais. Código pode pausa para fora do para , mas apenas escapar com exceção de Mapa .

Na minha opinião Mapa também não deve fim garantia de aplicação de função, enquanto para must. AFAIK nenhuma implementação python é atualmente capaz de fazer isso auto-paralelização.

Você pode mudar o seu map a alguns legal rosqueada ou multiprocessamento ou distribuídos estrutura de computação se você precisa. disco é um exemplo da distribuição, estrutura baseada resistentes a falhas erlang-e-pitão. Eu configurei ele em 2 caixas de 8 núcleos e agora o meu programa é executado 16 vezes mais rápido, graças ao conjunto Disco, no entanto eu tive que reescrever meu programa de compreensões lista e loops para mapear / reduzir.

É a mesma coisa para escrever um programa usando loops e compreensões lista e mapear / reduzir, mas quando você precisar dele para ser executado em um cluster, você pode fazê-lo quase de graça se você usou mapa / reduzir. Se não, bem, você vai ter que reescrever.

Cuidado: tanto quanto eu sei, python 2.x retorna uma lista em vez de uma iteração de mapa. Eu já ouvi isso pode ser contornado usando iter.imap() (nunca usei embora).

Use uma explícita para-loop quando você não precisa de uma lista de resultados de volta (por exemplo. Funções com efeitos colaterais).

Use uma compreensão da lista quando você precisa de uma lista de resultados de volta (por exemplo. Funções que retornam um valor baseado diretamente na entrada).

Use do mapa () quando você está tentando convencer os usuários Lisp que Python vale a pena usar. ;)

A principal vantagem do map é quando você deseja obter o resultado de algum cálculo sobre cada elemento em uma lista. Por exemplo, esse trecho dobra a cada valor em uma lista:

map(lambda x: x * 2, [1,2,3,4])  #=> [2, 4, 6, 8]

É importante notar que map retorna uma nova lista com os resultados. Não modificar a lista original no lugar.

Para fazer a mesma coisa com for, você teria que criar uma lista vazia e adicionar uma linha extra para o corpo for para adicionar o resultado de cada cálculo para a nova lista. A versão map é mais conciso e funcional.

Mapa às vezes pode ser mais rápido para funções internas do que de codificação manualmente um loop. Tente mapa de temporização (str, gama (1000000)) versus uma semelhante para o laço.

map(lambda item: item.my_func(), items)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top