'complex' function with string argument.

Chris Angelico rosuav at gmail.com
Mon Mar 17 13:03:19 EDT 2014


On Tue, Mar 18, 2014 at 3:18 AM, Mark H Harris <harrismh777 at gmail.com> wrote:
> You actually answered your own question, as you were asking it. If the doc
> says "whatever you do, don't push the purple button," well, leave the purple
> button alone.      :)   (I don't know, push it if you want)

https://www.wizards.com/magic/magazine/article.aspx?x=mtg/daily/mm/69

> If you monitor the PEP process, or have ever taken part in python-ideas, or
> python-dev (either directly, or just lurking) you will notice that python is
> developed through a very interesting active committee process (that is
> really something phenomenal; cool community).

Not really a committee, more of a champion-and-bikeshedders approach -
often with more than one level of champion, as when a PEP has an
author (the first champion) and either the BDFL or his delegate (the
second champion, whose role is usually just to say yay or nay). It's a
curious process, but one that works fairly well.

> How should one spell a complex number? Should we use i or j ? Should the
> imaginary part be set off somehow?  Should literals be parsed differently
> (or consistently) with correctly formed strings?  Who knows, beats me.
>
> consider:
>>>> complex( 3   +  2   j)
> SyntaxError: invalid syntax
>>>> complex( 3   +2j  )
> (3+2j)
>>>>
> I don't know... you tell me.

That's for the sake of parsing clarity. (Incidentally, the call to
complex() is redundant in each case.) Everything in Python consists of
tokens - those tokens, in your examples, are:

"complex", "(", whitespace, "3", whitespace, "+", whitespace, "2",
whitespace, "j", ")", end of line

and

"complex", "(", whitespace, "3", whitespace, "+", "2j", whitespace,
")", end of line

In the first case, the parser then has two symbol-type tokens ("2" and
"j") separated by whitespace, with no operator. That's a problem. Did
you mean "2+j", or "2==j", etc? Since j is perfectly natural as a
name, it's going to be interpreted that way.

In the second case, that translates into a perfectly valid parse tree,
because "2j" is an imaginary literal.

>>> ast.dump(ast.parse("complex( 3   +2j  )"))
"Module(body=[Expr(value=Call(func=Name(id='complex', ctx=Load()),
args=[BinOp(left=Num(n=3), op=Add(), right=Num(n=2j))], keywords=[],
starargs=None, kwargs=None))])"

The sole argument to complex() is an expression which sums the integer
3 and the imaginary 2j, which results in the complex (3+2j), which
complex() looks at and returns unchanged. And that's what you see.

>>>> complex('3+2j')
> (3+2j)
>>>> complex('3 +2j')
> Traceback (most recent call last):
>   File "<pyshell#17>", line 1, in <module>
>     complex('3 +2j')
> ValueError: complex() arg is a malformed string
>>>>
>
> Again, beats me.  I just don't know.

And now what you're looking at is the construction of a complex from a
string. Now, instead of going by the rules of the Python lexer, it
goes by the rules of the complex constructor. You can't use extra
spaces there. You could, of course, write your own function that
parses whatever format you like (including the use of i instead of j),
or you can use ast.literal_eval to parse a string based on Python's
lexing, but with complex(str) you follow the rules of complex(str).

> Philosophically, I tend to think about it this way. A complex number is like
> any other number. I would not form a PI string like this> ' 3 .14 1 5 9265 3
> . . .'   I would rather see it formed like so, '3.1415926535'

Right.

> This  '3 + 2j'  is not a number, its an algebraic sum.
>
> This  '3+2j'  is a complex number.  Ok, maybe not, but its closer to what we
> expect (I'm sorry, but I like  i  instead  of  j  )

Hmm. That's a pretty tricky distinction. In Python source code, those
two are identical, and they're both rendered as a sum. (Lexically. The
CPython optimizer, and presumably other Pythons' optimizers, will
notice at compile time that you're adding two literals, and store the
sum. But as you see from the AST above, it's the sum of two values.)
It's actually not possible, as far as I know, to truly represent a
complex number; all you can do is represent the sum of a real part and
an imaginary part.

> Also, philosophically, C ignores white space;  python does not.

That's not really anything to do with it. The two languages'
approaches to whitespace inside expressions are identical, save that
Python will only allow newlines if the expression is "clearly
unfinished", eg if it has unbalanced open parens. Horizontal
whitespace is fine in both languages. (Of course, C doesn't even
_have_ a complex literal notation, so the distinction is slightly
moot.)

ChrisA



More information about the Python-list mailing list