Perl is worse! (was: Python is Wierd!)

Grant Edwards nobody at nowhere.nohow
Fri Jul 28 01:56:07 EDT 2000


In article <slrn8o24mr.e7.grey at teleute.rpglink.com>, Steve Lamb wrote:
>
>    Ah, but getting back to that point I said to remember.
>
>foo = "a"
>foo = list(foo)
>
>    foo is not ['a'].

It is when I try it...

> It took a single element and made it a list. 

No, it took a sequence containing a single element and turned it into a list
containing a single element.  list() only works on sequences.  'a' is a
sequence of length 1.

>So we now know that a single element has a sequence.  

Not in the general case.

>Here is another sequence of a single element.
>
>foo = 1
>foo = list(foo)
>
>    Error.  Single element sequence.

No, 1 is not a sequence.  1 is an integer.  [1] is a sequence.  (1) is a
sequence.

>Remember, any sequence can either be a single value or a sequence.

I don't think so, but I'm not sure I understand what you're saying.  Can you
elaborate?

>Yet here we have a single value denied.  Quirks abound.

list() does not handle non-sequences.  You have run across a quirk, but it
isn't what you think it is.  It is this:

A string is a sequence of characters.  Passing a string to list() converts
that sequence of characters into a list of characters. 

Confusion may arise because a "character" is just a string of length 1. This
results in a rather recursive definition of a "string" as a sequence of
length-1 strings.  Therefore, we have the rather odd fact that

        'a'[0] == 'a'

This is important. 

'a' is a sequence that contains a single element.  

That element is 'a'.

This is why list('a') == ['a'].

No matter how many times you apply the [] operation to a length-1 string,
you get the same length-1 string.  This is a bit counter-intuitive, but the
other option is to have distinct character and string types.  If you do
that, then string manipulation gets a lot more messy.

>>>    a is now "['a', 'b', 'c']".  Which means we split a string up when
>>>converting to list but don't concatenate on the way back.

str() and list() are not inverse operations.  They are neither claimed nor
intended to be. 

There is no deterministic way to do the inverse of a list() operation
because there is no information in the list to tell you what sort of
sequence it used to be before it was converted into a list.

str() is defined as producing a more-or-less human-readable expression that
represents the object it is given. Passing a list to str() will generate a
string that (for simple cases) you can eval() to re-produce that list.

str() and eval() come much closer to being inverse operations -- but only
for simple cases.

If you _know_ that the list was the result of doing a list() on a string, then
the inverse operation to convert foo back from a list to a string is:  

  reduce(lambda x,y: x+y, foo)

If you need to do this a lot, then perhaps your complaint should be that
there's no built-in function to concatenate all of the strings in a given
sequence of strings.  Is there?

-- 
Grant Edwards                   grante             Yow!  Someone is DROOLING
                                  at               on my collar!!
                               visi.com            



More information about the Python-list mailing list