[Tutor] function call inside generator expression

Alan Gauld alan.gauld at yahoo.co.uk
Tue Oct 20 05:37:30 EDT 2020


On 20/10/2020 06:15, Manprit Singh wrote:

> lst_flt = (i for i in l if sum_digit(i) >= 13)
> print(*lst_flt)
> 
> The output is :
> 98 58 49 69
> 
> Which is the right answer. So as you can see i have used sum_digit(i) >= 13
> inside the generator expression, which is a function call. It is ok to use
> function calls inside generator expressions and comprehensions in the way as

As we have told you many times if the interpreter accepts it then
it is OK. The interpreter is the definitive answer to whether
things are OK to use.

As I said in a recent post the structure of a GE is:

[<value expression> <loops> <conditional expression>]

The expressions can be as arbirtrarily compex as you wish to make
them, Python does not care. You can call functions, create objects,
nest expressions. have as many compound expressions as you like.
It makes no difference to Python. Whether you (or your colleagues)
will be able to read or maintain them in 6 months time is quite
another matter.

> I have one more question. If you can see the function definition, you can
> found that i have done m = x, reason for doing this is actually i do not
> have the habit to modify the formal parameter of the function definition.

Except that m and x are the same thing. They are both just names
that refer to the same object.

> Now here x is immutable , modifying m  inside definition will not have
> any effect on x.

That is correct because you will be assigning a new object
to m so it will no longer be referencing the same object as x.

> If the function was made to accept a list, i would have> made a shallow copy of list by doing y = x[:] and then have performed any
> action on y to get the result so that the list passed to formal parameter> does not get affected. Need your sincere suggestion on this point.
What you describe is normal practice. If you get an immutable object
you might as well use it since you can't change it. If you get a
mutable object and don;t want to change the original you must make
a copy, you have no choice. It all depends on what you want to
achieve. If you are going to assign the modified object back
the argument at some point you may as well use the original
(and save a lot of copying) but if you want to end up with
both objects then you must make a copy.

But you say you'd make a shallow copy. That may not be enough,
it may need to be a deep copy, depending on what you are doing.
Consider:

L1 = [1,2,3]
L2 = [4,5,6]
def f(L):
    Lt = L[:]         # shallow copy
    lt[0].append(7)
    return Lt

L3 = f([L1,L2] # L1 is still modified despite the shallow copy

> Secondarily if there is any other efficient way to implement it ?

Implement what? Your original GE?, the function?
Or do you mean can we avoid doing the shallow copy?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list