Summary: The argument in list(arg) must be iterable. The argument in
str(arg) can be anything. Further, in [ a, b, c, d ] the content of the
literal must be read by the Python parser as a Python expression. But in
"this and that" the content need not be a Python expression.

Hi David

I find your suggestion a good one, in that to respond to it properly
requires a good understanding of Python. This deepens our understanding of
the language. I'm going to follow on from a contribution from Brendan
Barnwell.

Please consider the following examples

Similarity.
    >>> list( x*x for x in range(5) )
    [0, 1, 4, 9, 16]
    >>> [ x*x for x in range(5) ]
    [0, 1, 4, 9, 16]

Difference.
    >>> tmp = (x*x for x in range(5)) ; list(tmp)
    [0, 1, 4, 9, 16]
    >>> tmp = (x*x for x in range(5)) ; [ tmp ]
    [<generator object <genexpr> at 0x7fec02319678>]

Difference.
    >>> list( (x*x for x in range(5)) )
    [0, 1, 4, 9, 16]
    >>> [ (x*x for x in range(5)) ]
    [<generator object <genexpr> at 0x7fec02319620>]

Now consider ,
    >>> str( x * 2 for x in 'abc' )
    '<generator object <genexpr> at 0x7fec02319728>'

This last one genuinely surprised me. I was expecting 'aabbcc'. To
understand this, first note the quote marks in the response. Next recall
that str returns the string representation of the argument, via
type(obj).__str__(obj).

My understanding of the situation is that the list comprehension [ x*x for
x in range(5) ] is a shorthand for list( x*x for x in range(5) ). It works
because list takes an iterable as its argument (if it has one argument).
But str with one argument gives the string representation of an arbitrary
object. Here's an example.

    >>> list(None)
    TypeError: 'NoneType' object is not iterable
    >>> str(None)
    'None'

Here's what Brendan wrote: The difference between your proposal and
existing comprehensions is that strings are very different from lists,
dicts, sets, and generators (which are the things we currently have
comprehensions for).  The syntax for those objects is Python syntax, which
is strict and can include expressions that have meaning that is interpreted
by Python.  But strings can contain *anything*, and in general (apart from
f-strings) their content is not parsed by Python.

In a nutshell: The argument in list(arg) must be iterable. The argument in
str(arg) can be anything. Further, in [ a, b, c, d ] the content of the
literal must be a Python expression, whereas in "this and that" the content
need not be a Python expression.

I hope this helps.

Jonathan
_______________________________________________
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/HEORJVBWNK4TFRMFXPTLEHGWG6FDVPSM/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to