0

I have a list that I create inside of function1. I want to be able to access and modify it in function2. How can I do this without a global variable?

Neither function is nested within the other and I need to be able to generalize this for multiple lists in several functions.

I want to be able to access word_list and sentence_starter in other functions.

def Markov_begin(text):
    print create_word_lists(text)
    print pick_starting_point(word_list)
    return starting_list


def create_word_lists(filename):
   prefix_dict = {}    
   word_list = []
   sub_list = []
   word = ''

   fin = open(filename)
   for line in fin:
      the_line = line.strip()
      for i in line:
           if i not in punctuation:
               word+=(i)
           if i in punctuation:
               sub_list.append(word)
               word_list.append(sub_list)
               sub_list = []
               word = ''
      sub_list.append(word)
      word_list.append(sub_list)
   print 1
   return word_list

def pick_starting_point(word_list):
    sentence_starter = ['.','!','?']
    starting_list = []
    n = 0
    for n in range(len(word_list)-1):
        for i in word_list[n]:
            for a in i:
                if a in sentence_starter:
                    starting_list += word_list[n+1]
    print 2                
    return starting_list



def create_prefix_dict(word_list,prefix_length):
    while prefix > 0:
        n = 0
        while n < (len(word_list)-prefix):
            key = str(''.join(word_list[n]))
            if key in prefix_dict:
                prefix_dict[key] += word_list[n+prefix]
            else:
                prefix_dict[key] = word_list[n+prefix]
           n+=1
       key = ''
       prefix -=1

print Markov_begin('Reacher.txt')
AstroCB
  • 12,337
  • 20
  • 57
  • 73
ben
  • 665
  • 4
  • 10
  • 16

4 Answers4

4

You should refactor this as a class:

class MyWords(object):
  def __init__(self):
    self.word_list = ... #code to create word list

  def pick_starting_point(self):
    # do something with self.word_list
    return ...

Usage

words = MyWords()
words.pick_starting_point()
...
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
gahooa
  • 131,293
  • 12
  • 98
  • 101
3

You can simply use the list that first function creates as an argument of second function:

def some_list_function():
  # this function would generate your list
  return mylist

def some_other_function(mylist):
  # this function takes a list as an argument and process it as you want
  return result

some_other_function(some_list_function())

But if you need to use the list in multiple places (being processed by multiple functions) then storing it as a variable is not really a bad thing - even more, if your list generating function does some computing to generate the list, you're saving CPU by computing it only once.

SpankMe
  • 836
  • 1
  • 8
  • 23
  • I am not sure that I totally understand. Please see the newly added code which I hope will better explain my question. Thanks for your help. – ben Feb 03 '13 at 18:58
  • You simply pass a call to function generating your list as an argument (instead of global variable) to a call to function processing the list you want to generate. – SpankMe Feb 03 '13 at 19:04
0

If you do not want to a) use a global or b) return the list and pass it about, then you will have to use a class and hold your list in there.

The class route is best

X Tian
  • 766
  • 7
  • 13
  • Can you please explain how I would go about the 'return' route. Thanks. – ben Feb 03 '13 at 19:03
  • gahooa's solution use a class is best. But, you could Keep your lists in a local dictionary variable in your `Makov_begin` function. Then pass either the dict or specific list from the dict when calling your functions. eg `dictOfLists['wordlist'] = create_word_lists(text, dictOfLists)` – X Tian Feb 04 '13 at 01:12
-2

Functions can have attribute values (For examples, see question 338101.)

In the current context, you could save and reference items like prefix_dict, word_list, sub_list, and word as individual attributes of whichever function computes them, as illustrated in the following example. However, use of a class, as suggested in other answers, is more likely to be understandable and maintainable in the long-term .

For example:

In [6]: def fun1(v):
    fun1.li = range(v,8)
    return v+1
   ...: 

In [7]: def fun2(v):
    fun2.li = range(v,12) + fun1.li
    return v+2
   ...: 

In [8]: fun1(3)
Out[8]: 4

In [9]: fun2(6)
Out[9]: 8

In [10]: fun2.li
Out[10]: [6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7]
Community
  • 1
  • 1
James Waldby - jwpat7
  • 8,593
  • 2
  • 22
  • 37
  • -1: horrid advice for a python beginner. This would be like suggesting writing a meta-class that returns a generator which yields lambdas each processing a list comprehension that results in a mapped list. Ok, not quite like that, but seriously... – gahooa Feb 03 '13 at 20:32
  • @gahooa, nonsense, function attributes are easy to use and easy to understand, and a reasonable alternative to mention, given the wording of the question. In addition, I pointed out that "use of a class... is more likely to be understandable and maintainable in the long-term." – James Waldby - jwpat7 Feb 03 '13 at 21:03