fazistinho_
fazistinho_

Reputation: 335

Python Storing predefined lists in a module and editing them in an easy way

I'm not sure if this is best done with a class or if there's a neater way to do this.

I am writing a module, and in it I would like certain lists to be pre-defined and easily accessible, but also changeable. There will be a lot of these lists, maybe 20-30.

So example of these lists:

fruits = ['apple','pear','peach']
nuts = ['peanuts','cashew','almonds']

I also want to have two functions that allow people to add or remove items from this list:

my_mod.add(nuts, ['macademia','brazil'])
my_mod.remove(fruits, ['apple'])

So I was thinking of writing a class:

class Food:
    def __init__ (self):
        self.fruits = ['apple','pear','peach']
        self.nuts = ['peanuts','cashew','almonds']

    def add(self, add_items):
        self.<????> += add_items

But as you can see where I have the question marks, if I do it this way, I don't know how to add it to the list name supplied by the user.

Am I going about this there right way or is there a better way to achieve what I'd like?

The other idea I had was to use a dict and define it in the __init__ file of the Module

But I'm less keen on this idea, as I think it could be confusing.

Upvotes: 1

Views: 81

Answers (2)

Diego Suarez
Diego Suarez

Reputation: 961

There is a couple ways you can do this:

1 - With lists and "eval" function: This one works; but is not adviseable, beacause using "eval" if you don't know what your doing a user can inject malicious code.

class User:
    fruits = ['apple','pear','peach']
    nuts = ['peanuts','cashew','almonds']

    def add(self, _list, new_items=[]):
        l = eval('self.%s' % _list)
        l += new_items

    def remove(self, _list, item):
        l = eval('self.%s' % _list)
        l.remove(item)

if __name__ == '__main__':

    user1 = User()
    user1.add('fruits', ['orange', 'lemon'])
    print user1.fruits

    user1.remove('nuts', 'cashew')
    print user1.nuts

2 - Using python dictionaries.

class User:
    products = {
                    'fruits': ['apple','pear','peach'],
                    'nuts': ['peanuts','cashew','almonds'],
                }

    def add(self, _list, new_items=[]):
        try:
            self.products[_list] += new_items
        except KeyError:
            print 'The product list entered does not exist'

    def remove(self, _list, item):
        try:
            self.products[_list].remove(item)
        except KeyError:
            print 'The product list entered does not exist'

if __name__ == '__main__':

    user1 = User()
    user1.add('fruits', ['orange', 'lemon'])
    print user1.products['fruits']

    user1.remove('nuts', 'cashew')
    print user1.products['nuts']

    # When the user enters a nonexisting list
    user1.add('vegetables', ['onion'])

3 - Or the shortest way using a custom class of the list function.

class Mylist(list):
    def add(self, item):
        self.append(item)

class User:
    fruits = Mylist(['apple','pear','peach'])
    nuts = Mylist(['peanuts','cashew','almonds'])


if __name__ == '__main__':

    user1 = User()


    # TO ADD AN ITEM

    user1.fruits.add('orange')
    print user1.fruits


    # TO REMOVE AN ITEM, (list name must match name of list attribute inside)
    
    user1.nuts.remove('cashew')
    print user1.nuts

Upvotes: 1

Syamanthaka
Syamanthaka

Reputation: 1327

My suggestion would be to use an .xml or .json to define the contents of this list, like a sort of config. That way you can in your python code, simply read the root level tree and drill down programmatically, without the need to hard code anything, yet give the end users flexibility to add/remove. This can also mean that the end user changing this config file doesn't need to modify any python objects.

Let me illustrate. We have a config of user defined lists, say udl_config.xml which looks like:

<main>
    <fruits>
        <elem>apple</elem>
    .....
    </fruits>
    <nuts>
         .....
    </nuts>
    .....
</main>

Then in your python code you will have:

import xml.etree.ElementTree as ET
main_tree = ET.parse('udl_config.xml')
main_root = main_tree.getroot()

Use the find() and text() functions of xml parse library to drill down dynamically and perform necessary actions on them.

Upvotes: 0

Related Questions