generator

2

Well, I've been trying to optimize my code and found generator expressions, but I do not understand anything about it.

For example:

for mCp in mWithoutNone:
    for ctt in moradasCTT:
        if mCp[3] == ctt[3]:
            mWithCp4.append( ctt )
        else:
            pass

and wanted to type:

for mCp in mWithoutNone: # necessito mesmo deste for aqui por causa de uns if que tenho mais a frente
    mCp[3] == ctt[3] if mWithCp4.append( ctt ) else '' for ctt in moradasCTT

Full Code: link

    
asked by anonymous 05.07.2017 / 13:49

2 answers

1

( TL; DR )
Generating expressions, or genexp is a very broad subject in python, but maybe what you need is from list comprehensions or listcomps, I'll try to give you an example here using the for , liscomps, and a small sample of the genexps.

Let's say we have a list of numbers:

[1,2,5,10,20,4,5,7.18,55,34,14,44,89,70,64]

and we need to extract only divisible by 2. The first option would be:

Approach with for:

lst1 = [1,2,5,10,20,4,5,7.18,55,34,14,44,89,70,64]
lst2 = []

for number in lst1:
  if number%2==0:
    lst2.append(number)

Output:

print (lst2)
[2, 10, 20, 4, 34, 14, 44, 70, 64]

Now let's see what it would look like using listcomps.

Using listcomps:

## Usando listcomps ##
listcomps1 = [number for number in lst1 if number%2==0]

Output:

 print('listcomps1 (listcomps) :',listcomps1,'\n')
 listcomps1 (listcomps) : [2, 10, 20, 4, 34, 14, 44, 70, 64] 

Using genexp:

## Usando Expressões geradoras ##
gen1 = (number for number in lst1 if number%2==0)

In order to generate generative explanation, the syntax is identical to the listcomps generation, the only difference is the use of parentheses instead of brackets, but we will see the result:

output:

print('gen1 (genexp) : ', gen1,'\n')
gen1 (genexp) :  <generator object <genexpr> at 0x7fb9f4d705c8> 

See that the result was not a list but a objeto , this object could be 'manipulated' in several ways, we could do, for example:

print (list(gen1))

And we would get exactly what we get with listcomp, that is, [2, 10, 20, 4, 34, 14, 44, 70, 64] , but we 'kill' the generating expression and the result of the next example would generate an error.

Introducing the fifth element of genexp:

Considering that in the code, we did not include the command of the previous topic print (list(gen1)) , we could present any element of genexp without creating a whole list.

## Apresentando o 5 elemento da gen1?
print ('Quinto elemento: ', list(gen1)[5], '\n')

Output:

Quinto elemento:  14 

Showing that genexp "died" after execution:

## Mostrando que a gen1 foi executada e "morreu": ##
print ('O que aconteceu com gen1: ', list(gen1))

Output:

O que aconteceu com gen1:  []

So what's the benefit of genexps?
The main advantage of genexps is that they do not create, a priori, a whole list in memory. Of course, in examples like those presented here, there are no significant advantages, but suppose that in the above example the source is not an internal list but some external artifact (a database, for example) with thousands or millions of elements, and the need was to access specific elements in the result (like the fifth element, of the example), in this case, you would have only genexp and not the entire list. Of course the explanation was minimalist, for a broader view, see PEP 289 .

Run the code on repl.it.

    
05.07.2017 / 16:04
0

generator expressions has a simple syntax:

(expressão for variavel in interavel if condição)

If you want all values, you can omit the condition, hence:

(expressão, for variavel in iteravel)

Both are equivalent to:

def generator():
    for variavel in iteravel:
        if condição:
            yield expressão #poderia ser: variavel + 1.5 por exemplo

I'll make an example in Portuguese and Python

para cada numero entre 0 e 100 selecione os numeros divisiveis por 2

could be translated into python as:

>>> [numero for numero in range(0, 101) if numero % 2 == 0]
retorna:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100]

This is actually a list and not a generator because of the brackets. but if you replace the brackets with parentheses this becomes a generator object that just contains the expression but does not save all the values in a list, you can interact normally on it but can not access indexes because it does not store data.

#criando gerador
>>> gerador = (numero for numero in range(0, 101) if numero % 2 == 0)
>>> gerador
<generator object <genexpr> at 0x02DDF240>
#interando sobre ele
>>> for x in gerador:
    print(x)

0
2
4
6
8
10
12
14
...
#tentando acessar um indice falha pois geradores não são listas
>>> gerador[10]
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    gerador[10]
TypeError: 'generator' object is not subscriptable
>>> 
    
05.10.2018 / 18:26