MrPatterns
MrPatterns

Reputation: 4434

What is the Python equivalent of a jagged array?

After years of using Excel and learning VBA, I am now trying to learn Python. Here's the scenario:

I asked 7 summer camp counselors which activities they would like to be in charge of. Each student had a random number of responses, and there is no upper limit on the number of activities chosen. However, each activity is unique, and once "claimed" by a student it cannot claimed by any other counselor. The results were:

Adam: archery, canoeing
Bob: frisbee, golf, painting, trampoline
Carol: tennis, dance, skating
Denise: cycling
Eddie: horseback, fencing, soccer
Fiona: painting
George: basketball, football

I'm most familiar with VB (I am an old guy) and in the past I would have stored the above info in a jagged array. But since I'm new to Python, I am confused as to how to do this. I think a list of lists would work for me and here is my code. Let's say I have a list of counselors, and separate lists for each counselors' activities. How do I merge them or put them in one data structure? What am I doing wrong below? Thank you.

counselors = []
counselors = ['Adam','Bob','Carol','Denise','Eddie','Fiona','George']

#create a list of Carol's activities 
activities = []
activities = ['tennis','dance','skating']

counselors[2].append[(activities)]

Upvotes: 2

Views: 8387

Answers (1)

user8605709
user8605709

Reputation:

A jagged array in Python is pretty much a list of lists as you mentioned.

I would use a dictionary to store the counselors activity information, where the key is the name of the counselor, and the value is the list of activities the counselor will be in charge of e.g.

counselors_activities = {"Adam": ["archery", "canoeing"],
                      "Bob": ["frisbee", "golf", "painting", "trampoline"],
                      "Carol": ["tennis", "dance", "skating"],
                      "Denise": ["cycling"],
                      "Eddie": ["horseback", "fencing", "soccer"],
                      "Fiona": ["painting"],
                      "George": ["basketball", "football"]}

And access each counselor in the dictionary as such:

counselors_activites["Adam"] # when printed will display the result => ['archery', 'canoeing']

In regards to the question, I would store the list of activities available in a list, and anytime an activity is chosen, remove it from the list and add it to the counselor in the dictionary as such:

list_of_available_activities.remove("archery")
counselors_activities["Adam"].append("archery")

And if a counselor no longer was in charge of the activity, remove it from them and add it back to the list of available activities.

Update: I have provided a more fully fledged solution below based on your requirements from your comments.

Text file, activites.txt:

Adam: archery, canoeing
Bob: frisbee, golf, painting, trampoline
Carol: tennis, dance, skating
Denise: cycling
Eddie: horseback, fencing, soccer
Fiona: painting
George: basketball, football

Code:

#Set of activities available for counselors to choose from

set_of_activities = {"archery",
                  "canoeing",
                  "frisbee",
                  "golf",
                  "painting",
                  "trampoline",
                  "tennis",
                  "dance",
                  "skating",
                  "cycling",
                  "horseback",
                  "fencing",
                  "soccer",
                  "painting",
                  "basketball",
                  "football"}

with open('activities.txt', 'r') as f:
    for line in f:

        # Iterate over the file and pull out the counselor's names
        # and insert their activities into a list

        counselor_and_activities = line.split(':')
        counselor = counselor_and_activities[0]
        activities = counselor_and_activities[1].strip().split(', ')

    # Iterate over the list of activities chosen by the counselor and
    # see if that activity is free to choose from and if the activity
    # is free to choose, remove it from the set of available activities
    # and if it is not free remove it from the counselor's activity list

    for activity in activities:
        if activity in set_of_activities:
            set_of_activities.remove(activity)
        else:
            activities.remove(activity)

    # Insert the counselor and their chosen activities into the dictionary

    counselors_activities[counselor] = activities

# print(counselors_activities)

I have made one assumption with this new example, which is that you will already have a set of activities that can be chosen from already available:

I made the text file the same format of the counselors and their activities listed in the question, but the logic can be applied to other methods of storage.

As a side note and a correction from my second example previously, I have used a set to represent the list of activities instead of a list in this example. This set will only be used to verify that no counselor will be in charge of an activity that has already been assigned to someone else; i.e., removing an activity from the set will be faster than removing an activity from the list in worst case.

The counselors can be inserted into the dictionary from the notepad file without having to insert them into a list.

When the dictionary is printed it will yield the result:

{"Adam": ["archery", "canoeing"],
 "Bob": ["frisbee", "golf", "painting", "trampoline"],
 "Carol": ["tennis", "dance", "skating"],
 "Denise": ["cycling"],
 "Eddie": ["horseback", "fencing", "soccer"],
 "Fiona": [], # Empty activity list as the painting activity was already chosen by Bob
 "George": ["basketball", "football"]}

Upvotes: 4

Related Questions