By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,813 Members | 1,130 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,813 IT Pros & Developers. It's quick & easy.

Maintaining a list

P: n/a
I'm teaching myself programming using Python and want to build a list
inside a function (rather like using a static variable in a Fortran
subroutime - the list must not disappear as soon as the subroutine is
exited). What's the simplest way to do this?

I'd like to write something of the form
def myroutine(x)
mylist = mylist.append(x)
print mylist
Jul 18 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Thomas Philips wrote:
I'm teaching myself programming using Python and want to build a list
inside a function (rather like using a static variable in a Fortran
subroutime - the list must not disappear as soon as the subroutine is
exited). What's the simplest way to do this?

I'd like to write something of the form
def myroutine(x)
mylist = mylist.append(x)
append() returns None
print mylist
.
.
return

I'd like to call myroutine over and over again from a main program,
and want it to display the following behavior

1. The first time myroutine is called
myroutine("Item 1")
["Item 1"]

2. The second time myroutine is called
myroutine("Item 2")
["Item 1", "Item 2"]

3. The third time myroutine is called
myroutine("Item 3")
["Item 1", "Item 2", "Item 3"]

etc. etc.

The list must be initialized to an empty list before the first call,
and must be preserved between calls. I have not got to object oriented
programming as yet, so please keep the solution simple.

Sincerely

Thomas Philips


You're lucky, what you desired as a feature is a common pitfall: default
parameters are only initialized once:
def myroutine(item, lst=[]): .... lst.append(item)
.... return lst
.... myroutine("item1") ['item1'] myroutine("item2") ['item1', 'item2'] myroutine("item3") ['item1', 'item2', 'item3'] myroutine("item4")[:] = []
myroutine("item5") ['item5'] myroutine("item6") ['item5', 'item6']

This is just a rare case where you can use a mutable object as a default
argument. When you don't want to provide the possibility to change the list
from outside the function, just return a copy of it:
def myroutine(item, lst=[]):

.... lst.append(item)
.... return lst[:]

Peter
Jul 18 '05 #2

P: n/a
On 14 Feb 2004, Thomas Philips <- tk****@hotmail.com wrote:
subroutime - the list must not disappear as soon as the subroutine is
exited). What's the simplest way to do this? I'd like to write something of the form
def myroutine(x)
mylist = mylist.append(x)
print mylist
.
.
return I'd like to call myroutine over and over again from a main program,
and want it to display the following behavior 1. The first time myroutine is called
myroutine("Item 1")
["Item 1"] 2. The second time myroutine is called
myroutine("Item 2")
["Item 1", "Item 2"] [...] The list must be initialized to an empty list before the first call,
and must be preserved between calls. I have not got to object oriented
programming as yet, so please keep the solution simple.


So if you don't want to use a class and not a global var create a
closure or use the feature that an optional argument gets evaluated an
bound the time the function is defined.

So if you write:
myfunc(1) [1] myfunc(2) [1, 2] myfunc(3) [1, 2, 3]

always the list which had been created when the function was defined
gets used. You see that if you change the definition a bit.
def myfunc (item, lst = []): .... lst.append(item)
.... print id(lst)
.... return lst
.... myfunc(1) 10484012
[1] myfunc(2) 10484012
[1, 2] ##but .... myfunc(1, [])
10485068
[1] myfunc(3) 10484012
[1, 2, 3]
That may be what you want.

Another option is a closure.
def make_func (): .... lst = []
.... def func (item, lst = lst):
.... lst.append(item)
.... return lst
.... return func
.... myfunc = make_func()
myfunc(1) [1] myfunc(2) [1, 2]


KP

--
You know you've been sitting in front of your Lisp machine too long
when you go out to the junk food machine and start wondering how to
make it give you the CADR of Item H so you can get that yummie
chocolate cupcake that's stuck behind the disgusting vanilla one.
Jul 18 '05 #3

P: n/a
Thomas Philips wrote:
I'm teaching myself programming using Python and want to build a list
inside a function (rather like using a static variable in a Fortran
subroutime - the list must not disappear as soon as the subroutine is
exited). What's the simplest way to do this? [snip] The list must be initialized to an empty list before the first call,
and must be preserved between calls. I have not got to object oriented
programming as yet, so please keep the solution simple.


Work your way through these interactions.
def myrutine(x, mylist=[]): .... mylist.append(x)
.... print mylist
.... myrutine(1) [1] myrutine(2) [1, 2] myrutine(10) [1, 2, 10] b = []
myrutine(1, b) [1] b [1] myrutine(8) [1, 2, 10, 8] b [1]


One thing you need to remember is that list.append() returns None, not a
new list.

- Josiah
Jul 18 '05 #4

P: n/a
On 14 Feb 2004, Karl Pflästerer <- si****@12move.de wrote:
So if you write:


Here something got lost during c&p
def myfunc (item, lst = []): .... lst.append(item)
.... return lst
....
myfunc(1) [1] myfunc(2) [1, 2] myfunc(3)

[1, 2, 3]


KP

--
He took his vorpal sword in hand:
Long time the manxome foe he sought--
So rested he by the Tumtum tree,
And stood awhile in thought. "Lewis Carroll" "Jabberwocky"
Jul 18 '05 #5

P: n/a
In article <b4**************************@posting.google.com >,
Thomas Philips <tk****@hotmail.com> wrote:

The list must be initialized to an empty list before the first call,
and must be preserved between calls. I have not got to object oriented
programming as yet, so please keep the solution simple.


Unfortunately, while the other solutions given fit your technical
requirements, they're also what I (and probably others) would consider
unnatural for Python programs. That's partly because abuse of default
parameters and closures are actually two of the more difficult concepts
for people to learn correctly, IME. Here's a "less-simple" solution that
does what you want in a Pythonic fashion, though it still uses a trick:
class CallableList: .... def __init__(self):
.... self.data = []
.... def __call__(self, x):
.... self.data.append(x)
.... return self.data
.... myroutine = CallableList()
myroutine('1') ['1'] myroutine('spam') ['1', 'spam'] myroutine.data

['1', 'spam']
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"Argue for your limitations, and sure enough they're yours." --Richard Bach
Jul 18 '05 #6

P: n/a
Thomas Philips wrote:
I'm teaching myself programming using Python and want to build a list
inside a function (rather like using a static variable in a Fortran
subroutime - the list must not disappear as soon as the subroutine is
exited). What's the simplest way to do this? [snip] The list must be initialized to an empty list before the first call,
and must be preserved between calls. I have not got to object oriented
programming as yet, so please keep the solution simple.


How about using a global variable? Define a variable in
your main program:

mylist = []

def myroutine(x)
global mylist
mylist.append(x)
print mylist
return None

Then call it like this:
myroutine(1) [1] myroutine(2)

[1, 2]

and so forth.
There are disadvantages to using global variables, but
if you are looking for simplicity this is pretty simple.

--
Steven D'Aprano

Jul 18 '05 #7

P: n/a
Steve wrote:
Thomas Philips wrote:
I'm teaching myself programming using Python and want to build a list
inside a function (rather like using a static variable in a Fortran
subroutime - the list must not disappear as soon as the subroutine is
exited). What's the simplest way to do this?

...
mylist = []

def myroutine(x)
global mylist
mylist.append(x)
print mylist
return None


For the shortest (not simplest conceptually, but good to learn why it
works) solution, I'd propose:

mylist = []
myroutine = mylist.append
--
-Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.