-4

I already know how to change an element of a list into another one:

data = ["foo","bar","baz"]
for i in xrange(len(data)):
    if data[i] == "foo":
        data[i] = "baa"
print data

and the output is:

['baa', 'bar', 'baz']

but the item in the code I'm writing still hasn't changed; it still is "foo", the only change I can see is in the output.

I have a much bigger code which needs to change an item on the list based on user input. How do I keep a huge list and keep changing it (without actually touching the code)?

martineau
  • 119,623
  • 25
  • 170
  • 301
huhu
  • 31
  • 1
  • 5
  • 3
    Are you talking about data persistence? If yes, have you considered writing your data to a file (not the source code) and retrieving it from the file the next time the program is run? Self-modifying code is generally a bad idea. – blubberdiblub Apr 29 '17 at 19:22
  • 1
    When you change an element into a list, it remains until you change or remove it ... Can you clarify your question and post your code which doesn't work ? – Loïc G. Apr 29 '17 at 19:22
  • @blubberdiblub my problem is that my data is a huge list of lists; I have thought of putting it all on a text file but I can't find a way to arrange them into tables in the text file. – huhu Apr 29 '17 at 19:28
  • 2
    @huhu sounds like you need a better data structure, or just need some experience with serialization. The [`pickle`](https://docs.python.org/3/library/pickle.html) module is specifically made to do easy serializing of Python objects, you know. See [this possible helpful question](https://stackoverflow.com/questions/25464295/how-to-pickle-a-list) – Adam Smith Apr 29 '17 at 19:30
  • 2
    @huhu There is a multitude of ways to (serialize and) persist data. You could use JSON, YAML, XML, `shelve`, `pickle`, an SQLite3 database, CSV, etc. – blubberdiblub Apr 29 '17 at 19:30

3 Answers3

0

The easiest way to do this, without diving too deeply into self-rewriting code, or databases, or having to care about data structures, is to use the pickle module.

import pickle

with open("data.pickle", "wb") as f:
    data = ["foo","bar","baz"]
    pickle.dump(data, f)
# initial write to the data.pickle file. You would probably want to
# do this only if that file already exists, or else every run of the
# program will overwrite it with the default data

with open("data.pickle", "rb") as f:
    data = pickle.load(f)
# reload that data

# Let's modify it now.
data[0] = "spam"
data.append("eggs")
# data == ["spam", "bar", "baz", "eggs"]

with open("data.pickle", "wb") as f:
    pickle.dump(data, f)  # overwrite

with open("data.pickle", "rb") as f:
    new_data = pickle.load(f)

# new_data == data
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
0

When you are running a program, the program never actually changes.

What you are searching for is file IO.

You can read and write files to load and save results of your program:

with open('file.txt', 'w') as f: # 'w' to write the file
    f.write('useful data')

You can open this file with any text editor and see it contains the text useful data. To load the file, use read()

with open('file.txt', 'r') as f: # 'r' to read the file
    print(f.read()) # prints 'useful data'

Of course it would be useful to write more than one line:

with open('file.txt', 'w') as f: # 'w' to write the file
    f.writelines(['more', 'useful', 'data'])

Again, open it in a text editor to check the results.

To read the data, use readlines:

with open('file.txt', 'r') as f: # 'r' to read the file
    print(f.readlines()) # prints ['more', 'useful', data']

if you want to save more complex data as you mentioned in a comment you need to use a more complex file format or database. The file formats included in python are: JSON, CSV. sqlite is a database included with python.

Another option is pickle, but it has many drawbacks and should only be used for temporary storage.

JSON:

with open("file.json", "w") as f:
    json.dump({"complex": ["object"]}, f)

with open("file.json", "r") as f:
    x = json.load(f)

CSV:

with open('file.csv', 'w') as f:
    writer = csv.writer(f)
    writer.writerows([["fantastic", "table"], ["with many", "entries"]])

with open('file.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

For pickle and sqlite I encourage you to read the documentation

Azsgy
  • 3,139
  • 2
  • 29
  • 40
0

In the the normal operation of your python application you will not see a case where user input will change the entry in your python file.

1]    data = ["foo","bar","baz"]
2]    for i in xrange(len(data)):
3]        if data[i] == "foo":
4]            data[i] = "baa"
5]    print data

I added some line numbers to your code snippet above.

There is not sane way where you will take in user input and change the value as seen when you open the file at line 1. That doesn't mean that your list hasn't changed. Lists are mutable objects in python - this means their value can change. And you have done this in line 4 above. So you could have code that looks something like:

1]    data = ["foo","bar","baz"]
2]    print "Current List: " + str(data) 
3]    target = raw_input('Enter the item you would like to replace: ')
4]    replacement = raw_input('Enter the replacement value: ')
5]    for i in xrange(len(data)):
6]        if data[i] == target:
7]            data[i] = replacement
8]    print data

The user IS changing your list. But, this isn't long term. This exists only as long as your program runs.

As a short mechanism you could make a file where each entry in your list is on a single line in your list:

So the first time the program is run you would prepopulate the list from this file:

file.txt foo bar baz

Then your line 1 would look slightly different:

1]    with open('list.txt', 'r') as f:
2]        data = f.read().splitlines()
3]    print "Current List: " + str(data) 
4]    target = raw_input('Enter the item you would like to replace: ')
5]    replacement = raw_input('Enter the replacement value: ')
6]    for i in xrange(len(data)):
7]        if data[i] == target:
8]            data[i] = replacement
9]    print data
10]   with open('list.txt', 'w') as f:
11]       for entry in data:
12]           f.write(entry + '\n')

And, you know what, this totally works. For a simple enough situation this can be a solution. But a better solution is looking into persistent datastores like a database because that's what larger applications use to solve this problem.

Nahkki
  • 862
  • 8
  • 17