You ask "What data structure should I use in python to organize these groups?"
A key principle of top-down programming is that you do not decide the implementation of an abstract data structure until you have decided the operations that will be done on the structure as well as their relative frequencies and any other criteria (such as simplicity and memory usage). You have not stated that information, so we cannot recommend a particular implementation.
I can think of many ways to do what you ask: a tree, lists within lists, dictionaries within dictionaries, etc. Each has its advantages and disadvantages. I do wonder about one point. In your structure, every item at a new sub-level begins with '01', with the exception of '02.01.02 : Chris, Pete' which begins with '02'. Is that intentional? If you keep the otherwise apparent numbering, that opens up some simpler implementations.
With the added information in your comment, I recommend nested lists. Each data item has a sequence of indices that ends in zero, and anything else in the structure is a list that holds other data items and lists. In your example, if we let the entire structure be named a, then item 01 is a[1][0], item 01.01 is in a[1][1][0], item 02.01.02 is in a[2][1][2][0], and so on. This structure allows more items to be inserted later, so we can easily add item 01.01.01 without disturbing the other items. There is no need to store the item numbers in the structure: they are directly inferred from the position of the data items in the structure.
This implementation also allows the entire structure to have a data item, which has an empty item number and is stored in a[0]. A missing data item can be flagged by None, a blank item can be another empty item such as ''. Here is code that shows your example structure and code that prints it out.
def print_structure(structure, level=''):
"""Iterate through a heirarchical data structure, printing the data
items with their level numbers"""
for i, item in enumerate(structure):
if i == 0:
# Process each data item appropriately
if item is not None:
print(level + ' : ' + str(item))
else:
new_level = format(i, '02')
if level:
new_level = level + '.' + new_level
print_structure(item, new_level)
a = [None,
['Tony, John, Meredith',
['Alex, Fred, Melissa']],
['Alley, Henry, Natalie',
[None,
['?'],
['Chris, Pete']]],
['Andrew',
['Nancy, Peter, Harold']]]
print_structure(a)
In this implementation, each of your "groups" is a string. I put the group '?' where you said a group exists but did not state just what it is, and I put None where you did not say a data item exists. To modify the processing of the structure, just change the two lines after the comment Process each data item appropriately. The printout from the above code is
01 : Tony, John, Meredith
01.01 : Alex, Fred, Melissa
02 : Alley, Henry, Natalie
02.01.01 : ?
02.01.02 : Chris, Pete
03 : Andrew
03.01 : Nancy, Peter, Harold
Saving to and restoring from JSON is easy. This should meet your needs, though there are some modifications that could be made to either structure or code, of course.