On Fri, Jul 26, 2019 at 12:51:46PM -0000, Eli Berkowitz wrote:
> (This is my first time posting on any Python list; I've tried to search for 
> this idea and didn't find it but if I looked in the wrong places/this has 
> already been discussed I apologize and feel free to tell me!)
> 

> Say you have a list and you want to perform some operation on each 
> item in the list - but you don't need to store the result in a list.

Does that come up very often? That means you're performing the operation 
only for the side-effects. I can't think of many situations where that 
would be useful. And the few times that it does come up, there are 
usually better ways to get the result you want, e.g.:

# Instead of this:
for x in lst:
    L.append(x)

# Use this:
L.extend(lst)

# Instead of this:
for x in lst:
    print(x)

# Use this:
print(*lst, sep='\n')



> There are three simple ways of doing this, at least as far as I know: 
> ([print(item)] could be any expression, just using it as an example)
> 
> ```
> lst = [1, 2, 3, 4]
> 
> #1 
> for item in lst:
>     print(item)
>
> # 2
> [print(item) for item in lst]

No no no, this is wrong and bad, because you are building a list full of 
Nones that has to be thrown away afterwards. But you know that.

> # 3
> for item in lst: print(item)

Aside from being compressed to one line instead of two, that's identical 
to #1. They generate the same code, and both are perfectly fine if you 
have some reason for wanting to save a line.


> #1 - In my opinion, this should be a one line operation so #1 is not ideal.

Why should it be a one-liner? Do you have a shortage of vertical space 
to work with? Your comment here contradicts your comment about #3, where 
you say that making it a one-liner is "very unpythonic".


> #2 - It also shouldn't require storing results in array, to save 
> time/memory, so #2 is out.
> #3 - I think #3 is just not good syntax, it seems very unpythonic to 
> me - it breaks the norm that blocks go on their own lines. It does 
> seem the best of the three though and I know my assessment is kind of 
> subjective.

You can't have #1 and #3 at the same time. If it is unpythonic to have a 
loop on one line, then you need to split it over two lines. Inventing 
new syntax just so you can have a loop on one line when the language 
already permits loops on one line is unnecessary.


> I'm wondering if a possible alternative syntax could be a for-expression, 
> like there's if-expressions, which always evaluates to None:
> ```
> print(item) for item in lst
> ```

That clashes with the syntax for a generator comprehension. Generator 
comprehensions are funny beasts, because they require parentheses when 
they stand alone:

    it = expression for item in lst    # Syntax error.
    it = (expression for item in lst)  # Permitted.

But when the parens are already there, as in a function call, you can 
(and should) leave the gen comprehension brackets out:

    all((expression for item in lst))  # Unnecessary extra parens.
    all(expression for item in lst)    # Preferred.


Because of that, your suggested syntax would be ambiguous:

    function(expression for item in lst)

could mean you are calling function() with a single generator 
comprehension as argument, or you are evaluating a "for-expression" for 
its side-effects and then calling function() with None as argument.


> A more practical example of when this would be useful is extending list-2 
> with a modified version of list-1 - this syntax would avoid creating an 
> intermediate list (not sure if the way lists are implemented in python 
> removes this advantage by the way it resizes lists though).
> 
> ```
> lst1 = [1, 2, 3]
> lst2 = [4, 5, 6]
> lst1.append(item * 2) for item in lst1
> ```

lst2.extend(item*2 for item in lst1)

lst2.extend(map(lambda x: 2*x, lst1)


In my personal toolbox, I have this function:


def do(func, iterable, **kwargs):
    for x in iterable:
        func(x, **kwargs)


Which I can use like this:

do(print, lst)

But I hardly ever do, since most of the time there are simpler 
alternatives. But feel free to use it in your own code.


-- 
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/H3FEB4ZECGBPDBHKWTQLF34DZF6WKDGD/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to