Discussion:
Lists in Python versus other languages
(too old to reply)
Stefan Ram
2024-06-24 10:24:27 UTC
Permalink
Sebastian Wells <***@here.com.invalid> wrote or quoted:
|..etc, taking into account that Python "lists" are really
|arrays, and there's no real Lisp equivalent to tuples,

Well, you could say that, in LISP, the dotted pair

( 1 . ( 2 . NIL ))

represents the list (1 2) while

( 1 . 2 )

represent the tuple "1,2".

|but they're essentially arrays also.

On an implementation level, an array is cache-friendly, while
a linked list is not. LISP lists are linked lists, not arrays.

|Lisp, there's no reader that will give you the original structure
|from its string representation without having to also evaluate it

In Python, the ast module can yield the structure of a module
of Python code (including list and tuple literals) without
the need to execute that code.

Newsgroups: comp.lang.python
Sebastian Wells
2024-06-24 10:35:00 UTC
Permalink
taking into account that Python "lists" are really |arrays, and there's
no real Lisp equivalent to tuples,
Well, you could say that, in LISP, the dotted pair
( 1 . ( 2 . NIL ))
represents the list (1 2) while
( 1 . 2 )
represent the tuple "1,2".
|but they're essentially arrays also.
The thing that makes Python tuples different
from Python lists is that tuples are
immutable. Lisp doesn't have a type that
is "a list (or array) but it's immutable."
|Lisp, there's no reader that will give you the original structure |from
its string representation without having to also evaluate it
In Python, the ast module can yield the structure of a module of
Python code (including list and tuple literals) without the need to
execute that code.
It doesn't yield actual lists or tuples, so you can't use it the
way OP was suggesting, that is, the way you'd use the corresponding
Lisp feature.
Stefan Ram
2024-06-24 11:25:13 UTC
Permalink
Post by Sebastian Wells
The thing that makes Python tuples different
from Python lists is that tuples are
immutable. Lisp doesn't have a type that
is "a list (or array) but it's immutable."
Yeah, I was thinking about the mathematical term "tuple" here.

In math, one doesn't really have just "tuples," but rather
"2-tuples," "3-tuples," and so on. The number is a fixed part of the
tuple's type. So, if one's dealing with a tuple representation made
of dotted pairs in LISP, one'd need to know how many components are
in it to interpret it correctly. While a list in LISP (with something
like "replace CDR") can be dynamically extended, one can't extend a
tuple because its size is fixed. In that sense, a LISP tuple (in the
sense suggested by me) is more static than a LISP list.
Post by Sebastian Wells
It doesn't yield actual lists or tuples, so you can't use it the
way OP was suggesting, that is, the way you'd use the corresponding
Lisp feature.
If one wants to parse Python code, like a tuple, the ast module
does all the heavy lifting to set up an AST. Turning that into
a real Python tuple takes just a bit of postprocessing.

main.py

import ast as _ast

source = r'''
( 0, 1,( 2, 3 ))
'''[ 1: -1 ]

def postprocess( parse_result ):
if isinstance( parse_result, _ast.Module ):
return postprocess( parse_result.body[ 0 ] )
elif isinstance( parse_result, _ast.Expr ):
return postprocess( parse_result.value )
elif isinstance( parse_result, _ast.Tuple ):
return \
tuple( postprocess( element )for element in parse_result.elts )
elif isinstance( parse_result, _ast.Constant ):
return parse_result.value

print( postprocess( _ast.parse( source )))

stdout

(0, 1, (2, 3))

In the case of simple tuples (with no calls or something),
one can just use "literal_eval".

main.py

import ast

print( ast.literal_eval( '( 0, 1,( 2, 3 ))' ))

stdout

(0, 1, (2, 3))

.
Stefan Ram
2024-06-24 11:45:11 UTC
Permalink
Post by Stefan Ram
return postprocess( parse_result.body[ 0 ] )
return postprocess( parse_result.value )
return \
tuple( postprocess( element )for element in parse_result.elts )
return parse_result.value
Or, using "match":

def postprocess( parse_result ):
match parse_result:
case _ast.Module( body=[ entry ]):
return postprocess( entry )
case _ast.Expr( value=value ):
return postprocess( value )
case _ast.Tuple( elts=elements ):
return \
tuple( postprocess( element )for element in elements )
case _ast.Constant( value=value ):
return value

.

Loading...