• Lists in Python versus other languages

    From Stefan Ram@21:1/5 to Sebastian Wells on Mon Jun 24 10:24:27 2024
    Sebastian Wells <sebastian@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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sebastian Wells@21:1/5 to Stefan Ram on Mon Jun 24 10:35:00 2024
    On 24 Jun 2024 10:24:27 GMT, Stefan Ram wrote:

    Sebastian Wells <sebastian@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.

    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Stefan Ram on Mon Jun 24 11:45:11 2024
    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:
    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

    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

    .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Sebastian Wells on Mon Jun 24 11:25:13 2024
    Sebastian Wells <sebastian@here.com.invalid> wrote or quoted:
    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.

    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))

    .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)