Summary
Why is the output messy?
==> Because a thread may yield part way through executing a print statement
Why is aList not equal to [1, 2, 3, 4, 5, 6]?
==> Because the content of aList may change between reading from it and appending 
to it.
Output
The output is messy because it is being produced by python2's print statement 
from within threads, and the print statement is not threadsafe.  This means 
that a thread may yield while print is executing.  In the code in the 
question there multiple threads printing, so one thread may yield while 
printing, the other thread may start printing and then yield so producing the 
interleaved output seen by the OP.  IO operations such as writing to stdout 
are very slow in CPU terms, so it's quite likely that the operating system may 
pause a thread performing IO because thread is waiting on the hardware to do 
something.
For example, this code:
import threading
def printer():
    for i in range(2):
        print ['foo', 'bar', 'baz']
def main():
    threads = [threading.Thread(target=printer) for x in xrange(2)]
    for t in threads: 
        t.start()
    for t in threads:
        t.join()
produces this interleaved output:
>>> main()
['foo', 'bar'['foo', , 'bar', 'baz']
'baz']
['foo', ['foo', 'bar''bar', 'baz']
, 'baz']
The interleaving behaviour can be prevented by using a lock:
def printer():
    for i in range(2):
        with lock:
            print ['foo', 'bar', 'baz']
def main():
    global lock
    lock = threading.Lock()
    threads = [threading.Thread(target=printer) for x in xrange(2)]
    for t in threads: 
        t.start()
    for t in threads:
        t.join()
>>> main()
['foo', 'bar', 'baz']
['foo', 'bar', 'baz']
['foo', 'bar', 'baz']
['foo', 'bar', 'baz']
The contents of the list
The final content of aList will be [1, 2, 3, 4, 5, 6] if the statement
aList.append(aList[-1] + 1)
is executed atomically, that is without the current thread yielding to another 
thread which is also reading from and appending to aList.
However this not how threads work.  A thread may yield after reading 
the last element from aList or incrementing the value, so it is quite 
possible to have a sequence of event like this:
- Thread1 reads the value 2fromaList
- Thread1 yields
- Thread2 reads the value 2fromaList, then appends3
- Thread2 reads the value 3fromaList, then appends4
- Thread2 yields
- Thread1 appends 3
- Thread1 reads the value 3fromaList, then appends4
This leaves aList as [1, 2, 3, 4, 3, 4]
As with the print statements, this can be prevented by making threads acquire a lock before executing aList.append(aList[-1] + 1)
(Note that the list.append method is threadsafe in pure python code, so there is no risk that the value being appended could be corrupted.)