Lists and Tuples and Much More

S

Scott

I'm going to start grouping all my questions in one post as this is my
second today, and sorta makes me feel dumb to keep having to bother you all
with trivial questions. I'll just seperate my questions with:
-------------------------------------------------------------------------------------------
Now onto the issue:
List's and Tuple's
I don't see the distinction between the two. I mean, I understand that a
list is mutable and a tuple is immutable.
The thing that I dont understand about them is what, besides that, seperates
the two. I did a little experimentation to try to understand it better, but
only confused myelf more.

A list looks like this:

and a tuple looks like this:

Now you can add to a list, but not a tuple so:
[1, 2, 3, 4, 5, 6, (1, 2, 3, 4, 5, 6)]

Is that pretty much accurate? And which is better on resources....I'm
guessing a tuple seeing as it doesn't change.

And the last example brings up another question. What's the deal with a
tupple that has a list in it such as:
my_tupple = (1, 2, 3, 4, 5, [6, 7, 8, 9])

Now I read somewhere that you could change the list inside that tupple. But
I can't find any documentation that describes HOW to do it. The only things
I CAN find on the subject say, "Don't do it because its more trouble than
it's worth." But that doesn't matter to me, because I want to know
everything.
---------------------------------------------------------------------------------------------

Now there comes append. I read everywhere that append only add's 1 element
to the end of your list. But if you write:
my_list = [1, 2, 3, 4, 5, 6]
my_list.append([7, 8, 9, 10])
my_list
[1, 2, 3, 4, 5, 6, [7, 8, 9, 10]]

Is that because list's, no matter what they contain, are counted as 1
element?

And how would you sort the list that's in the list? I guess that goes in
conjunction with the section above, but still:
my_list = [6, 4, 3, 5, 2, 1]
my_list.append([7, 9, 8, 10])
my_list.sort()
my_list
[1, 2, 3, 4, 5, 6, [7, 9, 8, 10]]

This is, again, something I'm finding nothing on.
---------------------------------------------------------------------------------------------

Maybe I'm just not looking in the right spots. The only things I have as
learning aids are: this newsgroup ;p, http://diveintopython.org,
http://python.org/, Beggining Python: From Novice to Professional, and (now
don't laugh) Python for Dummies.
 
B

bearophileHUGS

Scott:

Others will give you many more answers, here is just a bit.
And how would you sort the list that's in the list? I guess that goes in
conjunction with the section above, but still:
my_list = [6, 4, 3, 5, 2, 1]
my_list.append([7, 9, 8, 10])
my_list.sort()
my_list

[1, 2, 3, 4, 5, 6, [7, 9, 8, 10]]

Such sorting may be impossible in Python 3.0 (comparing the order of
lists with integers may be seen as meaningless. Otherwise you can see
single numbers as lists of len=1, like another language does).

This is, again, something I'm finding nothing on.

Maybe because documentation requires some generalization capabilities.
A list is a single object, and it can contain a sequence of objects.

Bye,
bearophile
 
7

7stud

Now I read somewhere that you could change the
list inside that tupple. But I can't find any
documentation that describes HOW to do it.

t = (1, 2, ["red", "white"])
t[2][1] = "purple"
print t

t[2] returns the list, so the second line is equivalent to:

lst = t[2]
lst[1] = "purple"

That is exactly how you would access and change a list inside a list,
e.g.:

[1, 2, ["red", "white"]]
And which is better on resources....I'm guessing a tuple seeing
as it doesn't change.

I doubt it matters much unless you have several million lists v.
several million tuples. The reason you need to know about tuples is
because they are returned by some built in functions. Also, a key in
a dictionary can be a tuple, but not a list. But using a tuple as a
key in a dictionary is probably something you will never do.

Now there comes append. I read everywhere that append only add's 1
element to the end of your list. But if you write:
my_list = [1, 2, 3, 4, 5, 6]
my_list.append([7, 8, 9, 10])
my_list _li

[1, 2, 3, 4, 5, 6, [7, 8, 9, 10]]
Is that because list's, no matter what they contain, are counted as
1 element?

Each "element" in a list is associated with an index position. When
you append() to a list you are creating one additional index position
in the list and assigning the thing you append to that index
position. The thing you append becomes one element in the list, i.e.
it's associated with one index position in the list. As a result,
when you append(), the length of the list only increases by 1:
l = [1, 2]
len(l) 2
a = ["red", "white"]
l.append(a)
l [1, 2, ['red', 'white']]
len(l) 3


And how would you sort the list that's in the list?

By summoning up the list, and then sorting it:

t = (1, 2, ["red", "white", "ZZZ", "abc"])
t[2].sort()
print t
 
D

Daniel Nogradi

And the last example brings up another question. What's the deal with a
tupple that has a list in it such as:
my_tupple = (1, 2, 3, 4, 5, [6, 7, 8, 9])

Now I read somewhere that you could change the list inside that tupple. But
I can't find any documentation that describes HOW to do it. The only things
I CAN find on the subject say, "Don't do it because its more trouble than
it's worth." But that doesn't matter to me, because I want to know
everything.

You could change the list inside your tuple like this:
my_tupple = (1, 2, 3, 4, 5, [6, 7, 8, 9])
my_tupple[5].append(10)
my_tupple
(1, 2, 3, 4, 5, [6, 7, 8, 9, 10])


Now there comes append. I read everywhere that append only add's 1 element
to the end of your list. But if you write:
my_list = [1, 2, 3, 4, 5, 6]
my_list.append([7, 8, 9, 10])
my_list
[1, 2, 3, 4, 5, 6, [7, 8, 9, 10]]

Is that because list's, no matter what they contain, are counted as 1
element?
Yes.

And how would you sort the list that's in the list? I guess that goes in
conjunction with the section above, but still:
my_list = [6, 4, 3, 5, 2, 1]
my_list.append([7, 9, 8, 10])
my_list.sort()
my_list
[1, 2, 3, 4, 5, 6, [7, 9, 8, 10]]

How about:
my_list = [6, 4, 3, 5, 2, 1]
my_list.append([7, 9, 8, 10])
my_list[6].sort()
my_list
[6, 4, 3, 5, 2, 1, [7, 8, 9, 10]]


HTH,
Daniel
 
B

Ben Finney

Scott said:
I'm going to start grouping all my questions in one post as this is
my second today, and sorta makes me feel dumb to keep having to
bother you all with trivial questions.

No, please don't do that. Separate questions leading to separate
discussions should have separate threads. Post them as separate
messages, each with a well-chosen Subject field for the resulting
thread.
 
G

Gabriel Genellina

List's and Tuple's
I don't see the distinction between the two. I mean, I understand that a
list is mutable and a tuple is immutable.
The thing that I dont understand about them is what, besides that,
seperates
the two.

Perhaps this old post from 2001 can explain a bit:
http://groups.google.com/group/comp...ead/thread/7eaf9fe92b4c7e47/#78e78f179a893526
Or perhaps this one from 1998:
http://groups.google.com/group/comp...read/thread/358ef18309812fbb/14199e16f119a020
Now you can add to a list, but not a tuple so:
[1, 2, 3, 4, 5, 6, (1, 2, 3, 4, 5, 6)]

Is that pretty much accurate? And which is better on resources....I'm
guessing a tuple seeing as it doesn't change.

Yes. Tuples are immutable - once created, they can't change.
And the last example brings up another question. What's the deal with a
tupple that has a list in it such as:
my_tupple = (1, 2, 3, 4, 5, [6, 7, 8, 9])

Now I read somewhere that you could change the list inside that tupple.
But
I can't find any documentation that describes HOW to do it. The only
things
I CAN find on the subject say, "Don't do it because its more trouble than
it's worth." But that doesn't matter to me, because I want to know
everything.

The *contents* of the list can be changed, but not the list itself:

my_tupple[5].append(10)
del my_tupple[5][2]

my_tupple will always contain *that* list, whatever you put inside it.
(Do not confuse the list object -a container- with the objects contained
inside it)
Now there comes append. I read everywhere that append only add's 1
element
to the end of your list. But if you write:
my_list = [1, 2, 3, 4, 5, 6]

my_list contains 6 elements: len(my_list)==6
my_list.append([7, 8, 9, 10])
my_list
[1, 2, 3, 4, 5, 6, [7, 8, 9, 10]]

my_list now contains 7 elements: len(my_list)==7
Its seventh element happens to be a list itself, but that doesn't matter:
my_list sees it as a single object like any other.
Is that because list's, no matter what they contain, are counted as 1
element?

Exactly. Lists or whatever object you want, if you append it to my_list,
my_list grows by one element. It doesn't care *what* it is - it's a new
element.
And how would you sort the list that's in the list? I guess that goes in
conjunction with the section above, but still:
my_list = [6, 4, 3, 5, 2, 1]
my_list.append([7, 9, 8, 10])
my_list.sort()
my_list
[1, 2, 3, 4, 5, 6, [7, 9, 8, 10]]

To sort my_list, you call the sort method on my_list: my_list.sort()
To sort "the list that's in the list", i.e. my_list[6], you call the sort
method on "the list that's in the list": my_list[6].sort()
This is, again, something I'm finding nothing on.

You call a method on any object using any_object.method_name(some,
parameters, may_be=required)
any_object may be any arbitrary expression, like my_list[6] above
Maybe I'm just not looking in the right spots. The only things I have as
learning aids are: this newsgroup ;p, http://diveintopython.org,
http://python.org/, Beggining Python: From Novice to Professional, and
(now
don't laugh) Python for Dummies.

That's fine - just keep programming, and have fun.
 
7

7stud

Yes. Tuples are immutable - once created, they can't change.

Just to explain that statement a little better. If you do this:


t = (1, 2, ["red", "white"])
t[2].append("purple")
print t #(1, 2, ['red', 'white', 'purple'])


It sure looks like t changed, and therefore t is NOT immutable--and
the whole "tuples are immutable" mantra is a lie. However, the list
itself isn't actually stored inside t. What's stored inside t is
python's internal id for the list. So suppose python gave the list
the internal id: 10008. The tuple really looks like this:

t = (1, 2, <10008>)

And no matter what you do to the list: append() to it, sort() it,
etc., the list's id remains the same. In that sense, the tuple is
immutable because the id stored in the tuple never changes.

In actuality, the numbers 1 and 2 aren't stored in the list either--
python has internal id's for them too, so the tuple actually looks
like this:

t = (<56687>, <93413>, <10008>)
| | |
| | |
| | |
V V V
1 2 ["red", "white", "purple"]


Because of that structure, you can create situations like this:
lst = ["red", "white"]
t1 = (1, 2, lst)
t2 = (15, 16, lst)
print t1 (1, 2, ['red', 'white'])
print t2 (15, 16, ['red', 'white'])
lst.append("purple")
print lst ['red', 'white', 'purple']
print t1 (1, 2, ['red', 'white', 'purple'])
print t2 (15, 16, ['red', 'white', 'purple'])

lst, t1, and t2 all refer to the same list, so when you change the
list, they all "see" that change. In other words, the names lst,
t1[2], and t2[2] all were assigned the same python id for the original
list ["red", "white"]. Since all those names refer to the same list,
any of those names can be used to change the list.
 
M

mensanator

I'm going to start grouping all my questions in one post as this is my
second today, and sorta makes me feel dumb to keep having to bother you all
with trivial questions. I'll just seperate my questions with:
---------------------------------------------------------------------------­----------------
Now onto the issue:
List's and Tuple's
I don't see the distinction between the two. I mean, I understand that a
list is mutable and a tuple is immutable.
The thing that I dont understand about them is what, besides that, seperates
the two. I did a little experimentation to try to understand it better, but
only confused myelf more.

A list looks like this:
my_list = [1, 2, 3, 4, 5, 6]

and a tuple looks like this:

Now you can add to a list, but not a tuple so:

[1, 2, 3, 4, 5, 6, (1, 2, 3, 4, 5, 6)]

Is that pretty much accurate? And which is better on resources....I'm
guessing a tuple seeing as it doesn't change.

And the last example brings up another question. What's the deal with a
tupple that has a list in it such as:
my_tupple = (1, 2, 3, 4, 5, [6, 7, 8, 9])

Now I read somewhere that you could change the list inside that tupple. But
I can't find any documentation that describes HOW to do it. The only things
I CAN find on the subject say, "Don't do it because its more trouble than
it's worth." But that doesn't matter to me, because I want to know
everything.
---------------------------------------------------------------------------­------------------

Now there comes append. I read everywhere that append only add's 1 element
to the end of your list. But if you write:>>> my_list = [1, 2, 3, 4, 5, 6]
my_list.append([7, 8, 9, 10])
my_list

[1, 2, 3, 4, 5, 6, [7, 8, 9, 10]]

Is that because list's, no matter what they contain, are counted as 1
element?

Right, but I didn't see the following mentioned elsewhere, so note
that:

What you probably wanted to use to add [7,8,9,10] to your list was
..extend() not .append().
my_list = [1, 2, 3, 4, 5, 6]
my_list.extend([7, 8, 9, 10])
my_list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


And how would you sort the list that's in the list? I guess that goes in
conjunction with the section above, but still:>>> my_list = [6, 4, 3, 5, 2, 1]
my_list.append([7, 9, 8, 10])
my_list.sort()
my_list

[1, 2, 3, 4, 5, 6, [7, 9, 8, 10]]

This is, again, something I'm finding nothing on.
---------------------------------------------------------------------------­------------------

Maybe I'm just not looking in the right spots. The only things I have as
learning aids are: this newsgroup ;p,http://diveintopython.org,http://python.org/, Beggining Python: From Novice to Professional, and (now
don't laugh) Python for Dummies.
 
M

Mel Wilson

Scott said:
Now I read somewhere that you could change the list inside that tupple. But
I can't find any documentation that describes HOW to do it. The only things
I CAN find on the subject say, "Don't do it because its more trouble than
it's worth." But that doesn't matter to me, because I want to know
everything.

Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02)
[GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> aa = (1, 2, [3, 4])
>>> aa (1, 2, [3, 4])
>>> aa[2].append ((True, False))
>>> aa (1, 2, [3, 4, (True, False)])
>>>

Like that.
Mel.
 
P

Paul McGuire

I'm going to start grouping all my questions in one post as this is my
second today, and sorta makes me feel dumb to keep having to bother you all
with trivial questions.

You might also investigate the python tutorial mailing list, which
covers many of these basic topics without seeming to be bothered by
much of anything.

-- Paul
 
S

Steven D'Aprano

[1, 2, 3, 4, 5, 6, [7, 9, 8, 10]]

Such sorting may be impossible in Python 3.0 (comparing the order of
lists with integers may be seen as meaningless. Otherwise you can see
single numbers as lists of len=1, like another language does).

And such sorting may be impossible in ten billion years when the sun
explodes, but is it really necessary to confuse a newbie who is having
problems with basic concepts with what "may" happen in some future version
of Python?

It would be one thing if sorting such lists was depreciated, but it isn't,
so I think as far as the Original Poster is concerned, that's just
muddying the water.
 
S

Scott

7stud said:
Yes. Tuples are immutable - once created, they can't change.

Just to explain that statement a little better. If you do this:


t = (1, 2, ["red", "white"])
t[2].append("purple")
print t #(1, 2, ['red', 'white', 'purple'])


It sure looks like t changed, and therefore t is NOT immutable--and
the whole "tuples are immutable" mantra is a lie. However, the list
itself isn't actually stored inside t. What's stored inside t is
python's internal id for the list. So suppose python gave the list
the internal id: 10008. The tuple really looks like this:

t = (1, 2, <10008>)

And no matter what you do to the list: append() to it, sort() it,
etc., the list's id remains the same. In that sense, the tuple is
immutable because the id stored in the tuple never changes.

In actuality, the numbers 1 and 2 aren't stored in the list either--
python has internal id's for them too, so the tuple actually looks
like this:

t = (<56687>, <93413>, <10008>)
| | |
| | |
| | |
V V V
1 2 ["red", "white", "purple"]


Because of that structure, you can create situations like this:
lst = ["red", "white"]
t1 = (1, 2, lst)
t2 = (15, 16, lst)
print t1 (1, 2, ['red', 'white'])
print t2 (15, 16, ['red', 'white'])
lst.append("purple")
print lst ['red', 'white', 'purple']
print t1 (1, 2, ['red', 'white', 'purple'])
print t2 (15, 16, ['red', 'white', 'purple'])

lst, t1, and t2 all refer to the same list, so when you change the
list, they all "see" that change. In other words, the names lst,
t1[2], and t2[2] all were assigned the same python id for the original
list ["red", "white"]. Since all those names refer to the same list,
any of those names can be used to change the list.
*********************************************************************
This is exactly the type of explaination I'm looking for. Thank you much!!!
 
H

Hendrik van Rooyen

7stud said:
.......... But using a tuple as a
key in a dictionary is probably something you will never do.

Yikes! I do this all the time...

Think of an address in any one town.
It has a Street, and a number
(could be more complex, like a sub number for an apartment
in a block, but lets ignore that for now)

so:
addy = ("First Avenue", 10)
Residents = {addy:"Frank Everyman",......}

To make a thing where you can look up who lives at a place...
(this is simplistic of course, for illustrative purposes - few people
live completely alone. - it should be at least a list, or possibly a dict
by surname...)

I find that when I do this, I almost invariably also create the
inverse dict:

Addresses = {"Frank Everyman":addy,.....}

So that you can get at stuff from all directions. If you keep it
up you have a home made relational database if you are not careful...

But if you limit it to one thing and its inverse, its quite useful, and it
would be nice to have one "doubledict" that can be accessed as speedily
from either end...

Sort of an internally linked list of mixed hashed immutables, where:

doubledict["Frank Everyman"] yields addy, and
doubledict[addy] yields "Frank Everyman"

It would have direct applicability in things like the label table in
an assembler, for debugging and so on.

- Hendrik
 
J

James Stroud

Hendrik said:
.......... But using a tuple as a
key in a dictionary is probably something you will never do.


Yikes! I do this all the time...

Think of an address in any one town.
It has a Street, and a number
(could be more complex, like a sub number for an apartment
in a block, but lets ignore that for now)

so:
addy = ("First Avenue", 10)
Residents = {addy:"Frank Everyman",......}

To make a thing where you can look up who lives at a place...
(this is simplistic of course, for illustrative purposes - few people
live completely alone. - it should be at least a list, or possibly a dict
by surname...)

I find that when I do this, I almost invariably also create the
inverse dict:

Addresses = {"Frank Everyman":addy,.....}

So that you can get at stuff from all directions. If you keep it
up you have a home made relational database if you are not careful...

But if you limit it to one thing and its inverse, its quite useful, and it
would be nice to have one "doubledict" that can be accessed as speedily
from either end...

Sort of an internally linked list of mixed hashed immutables, where:

doubledict["Frank Everyman"] yields addy, and
doubledict[addy] yields "Frank Everyman"

It would have direct applicability in things like the label table in
an assembler, for debugging and so on.

- Hendrik

I'm thinking that, to avoid big a lot of ambiguity, such a double dict
would need to be implemented as two distinctly referenced data structures:

class DD(object):
def __init__(self, adict):
self._fwd = {}
self._fwd.update(adict)
self._bkwk = dict(v,k for k,v in adict.items())
def fwd(self, k)
return self._fwd[k]
def bkwd(self, k)
return self._bkwd[k]
def __setitem__(self, k, v):
self._fwd[k] = v
self._bkwd[v] = k
def __getitem__(self, k):
if (k in self._fwd) and (k in self._bkwd):
raise KeyError, 'Which do I look in first?'
else:
raise KeyError, 'Too much guesswork. Use fwd() or bkwd().'

James
 
A

Alex Martelli

7stud said:
It sure looks like t changed, and therefore t is NOT immutable--and
the whole "tuples are immutable" mantra is a lie. However, the list

<http://mail.python.org/pipermail/python-list/2002-April/140258.html>

"""
So, "the statue that points to Hotel Belfiore" had suddenly
become "the statue that points to Da Carlo"...! Amazing
isn't it? Considering that marble isn't very fluid and the
statue had not been moved or disturbed in any way...?
"""


Alex
 
H

Hendrik van Rooyen

James Stroud said:
Hendrik van Rooyen wrote:
But if you limit it to one thing and its inverse, its quite useful, and it
would be nice to have one "doubledict" that can be accessed as speedily
from either end...

Sort of an internally linked list of mixed hashed immutables, where:

doubledict["Frank Everyman"] yields addy, and
doubledict[addy] yields "Frank Everyman"

It would have direct applicability in things like the label table in
an assembler, for debugging and so on.

- Hendrik

I'm thinking that, to avoid big a lot of ambiguity, such a double dict
would need to be implemented as two distinctly referenced data structures:

not sure that I agree with this - what I have in mind is almost like this:

{a:b,b:a,.....} - but avoiding the overhead of storing the "keys" and "data"
twice...

Guess at notation:

{<a:b>,<c:d>,....} - I know the <> is ugly so lets try:

{(a:b),(c:d),...} - not much better...

class DD(object):
def __init__(self, adict):
self._fwd = {}
self._fwd.update(adict)
self._bkwk = dict(v,k for k,v in adict.items())
def fwd(self, k)
return self._fwd[k]
def bkwd(self, k)
return self._bkwd[k]
def __setitem__(self, k, v):
self._fwd[k] = v
self._bkwd[v] = k
def __getitem__(self, k):
if (k in self._fwd) and (k in self._bkwd):
raise KeyError, 'Which do I look in first?'
else:
raise KeyError, 'Too much guesswork. Use fwd() or bkwd().'

James

This is the problem - you can also do it with two dicts, but then you have to
do try-except and handle KeyError if you guess wrong. This is what I have
been doing.

I think that trying to go "back and forth" is a mistake - easier to just have
one
link, and store "thing" and "pointer to thing's partner".

In practice you would probably either "know" what you are dealing with
because of where you got the thing you are looking up from, or in true
duck typing style you would not "care".

On the other hand, if you store two links, then you can have:

"thing", "pointer to next thing in group", "pointer to previous thing in group"

and then you can have something like:

dd={(a:b:c),(d:e:f:g:h),....}

and that would return a list [a,b,c], from any of dd[a], dd, dd][c],
and likewise for "entry points" of d,e,f,g, or h, to yield [d,e,f,g,h]

This makes me think that the correct notation would be:

{[a,b,c],[d,e,f,g,h],...}

but maybe not because it looks like a set of lists...

then how about:

{[a:b:c],[d:e:f:g:h],...}

and yes I know that:

{[a:b:c:f],[d:e:f:g:h],...} - can't be done using
only two pointers, not even with fancy footwork

- Hendrik
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top