Maintaining a list

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Thomas Philips

    Maintaining a list

    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
  • Peter Otten

    #2
    Re: Maintaining a list

    Thomas Philips wrote:
    [color=blue]
    > 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 )[/color]

    append() returns None
    [color=blue]
    > 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[/color]

    You're lucky, what you desired as a feature is a common pitfall: default
    parameters are only initialized once:
    [color=blue][color=green][color=darkred]
    >>> def myroutine(item, lst=[]):[/color][/color][/color]
    .... lst.append(item )
    .... return lst
    ....[color=blue][color=green][color=darkred]
    >>> myroutine("item 1")[/color][/color][/color]
    ['item1'][color=blue][color=green][color=darkred]
    >>> myroutine("item 2")[/color][/color][/color]
    ['item1', 'item2'][color=blue][color=green][color=darkred]
    >>> myroutine("item 3")[/color][/color][/color]
    ['item1', 'item2', 'item3'][color=blue][color=green][color=darkred]
    >>> myroutine("item 4")[:] = []
    >>> myroutine("item 5")[/color][/color][/color]
    ['item5'][color=blue][color=green][color=darkred]
    >>> myroutine("item 6")[/color][/color][/color]
    ['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:
    [color=blue][color=green][color=darkred]
    >>> def myroutine(item, lst=[]):[/color][/color][/color]
    .... lst.append(item )
    .... return lst[:]

    Peter

    Comment

    • Karl Pflästerer

      #3
      Re: Maintaining a list

      On 14 Feb 2004, Thomas Philips <- tkpmep@hotmail. com wrote:
      [color=blue]
      > subroutime - the list must not disappear as soon as the subroutine is
      > exited). What's the simplest way to do this?[/color]
      [color=blue]
      > I'd like to write something of the form
      > def myroutine(x)
      > mylist = mylist.append(x )
      > print mylist
      > .
      > .
      > return[/color]
      [color=blue]
      > I'd like to call myroutine over and over again from a main program,
      > and want it to display the following behavior[/color]
      [color=blue]
      > 1. The first time myroutine is called
      > myroutine("Item 1")
      > ["Item 1"][/color]
      [color=blue]
      > 2. The second time myroutine is called
      > myroutine("Item 2")
      > ["Item 1", "Item 2"][/color]
      [...][color=blue]
      > 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.[/color]

      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:
      [color=blue][color=green][color=darkred]
      >>> myfunc(1)[/color][/color][/color]
      [1][color=blue][color=green][color=darkred]
      >>> myfunc(2)[/color][/color][/color]
      [1, 2][color=blue][color=green][color=darkred]
      >>> myfunc(3)[/color][/color][/color]
      [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.
      [color=blue][color=green][color=darkred]
      >>> def myfunc (item, lst = []):[/color][/color][/color]
      .... lst.append(item )
      .... print id(lst)
      .... return lst
      ....[color=blue][color=green][color=darkred]
      >>> myfunc(1)[/color][/color][/color]
      10484012
      [1][color=blue][color=green][color=darkred]
      >>> myfunc(2)[/color][/color][/color]
      10484012
      [1, 2][color=blue][color=green][color=darkred]
      >>> ##but[/color][/color][/color]
      .... myfunc(1, [])
      10485068
      [1][color=blue][color=green][color=darkred]
      >>> myfunc(3)[/color][/color][/color]
      10484012
      [1, 2, 3]


      That may be what you want.

      Another option is a closure.
      [color=blue][color=green][color=darkred]
      >>> def make_func ():[/color][/color][/color]
      .... lst = []
      .... def func (item, lst = lst):
      .... lst.append(item )
      .... return lst
      .... return func
      ....[color=blue][color=green][color=darkred]
      >>> myfunc = make_func()
      >>> myfunc(1)[/color][/color][/color]
      [1][color=blue][color=green][color=darkred]
      >>> myfunc(2)[/color][/color][/color]
      [1, 2][color=blue][color=green][color=darkred]
      >>>[/color][/color][/color]



      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.

      Comment

      • Josiah Carlson

        #4
        Re: Maintaining a list

        Thomas Philips wrote:
        [color=blue]
        > 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?[/color]
        [snip][color=blue]
        > 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.[/color]

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

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

        - Josiah

        Comment

        • Karl Pflästerer

          #5
          Re: Maintaining a list

          On 14 Feb 2004, Karl Pflästerer <- sigurd@12move.d e wrote:
          [color=blue]
          > So if you write:[/color]

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

          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" "Jabberwock y"

          Comment

          • Aahz

            #6
            Re: Maintaining a list

            In article <b4a8ffb6.04021 31633.1cb220d6@ posting.google. com>,
            Thomas Philips <tkpmep@hotmail .com> wrote:[color=blue]
            >
            >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.[/color]

            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:
            [color=blue][color=green][color=darkred]
            >>> class CallableList:[/color][/color][/color]
            .... def __init__(self):
            .... self.data = []
            .... def __call__(self, x):
            .... self.data.appen d(x)
            .... return self.data
            ....[color=blue][color=green][color=darkred]
            >>> myroutine = CallableList()
            >>> myroutine('1')[/color][/color][/color]
            ['1'][color=blue][color=green][color=darkred]
            >>> myroutine('spam ')[/color][/color][/color]
            ['1', 'spam'][color=blue][color=green][color=darkred]
            >>> myroutine.data[/color][/color][/color]
            ['1', 'spam']
            --
            Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

            "Argue for your limitations, and sure enough they're yours." --Richard Bach

            Comment

            • Steve

              #7
              Re: Maintaining a list

              Thomas Philips wrote:
              [color=blue]
              > 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?[/color]
              [snip][color=blue]
              > 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.[/color]

              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:
              [color=blue][color=green][color=darkred]
              >>> myroutine(1)[/color][/color][/color]
              [1][color=blue][color=green][color=darkred]
              >>> myroutine(2)[/color][/color][/color]
              [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

              Comment

              • Scott David Daniels

                #8
                Re: Maintaining a list

                Steve wrote:
                [color=blue]
                > Thomas Philips wrote:[color=green]
                >> 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?[/color]
                >...
                > mylist = []
                >
                > def myroutine(x)
                > global mylist
                > mylist.append(x )
                > print mylist
                > return None[/color]

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

                mylist = []
                myroutine = mylist.append


                --
                -Scott David Daniels
                Scott.Daniels@A cm.Org

                Comment

                Working...