Search code examples
pythonlistenumerate

enumerating a list in a list


I have a date with events that happened on the date. I want to enumerate the list of events on the date when i show the calendar.

Also I need to be able to delete an event from the list.

def command_add(date, event, calendar):
    if date not in calendar:
        calendar[date] = list()
    calendar[date].append(event)


calendar = {}
command_add("2015-10-29", "Python class", calendar)
command_add("2015-10-12", "Eye doctor", calendar)
command_add("2015-10-12", "lunch with sid", calendar)
command_add("2015-10-29", "Change oil in blue car", calendar)
print(calendar)

def command_show(calendar):
    for (date, event) in calendar:
       print(date, enumerate(event))

command_show(calendar)

I thought that this would let me access the secondary list under the date and enumerate it but I get an error.

Example out:

command_show(calendar)
    2015-10-20:
        0: stackover flow sign up
    2015-11-01:
        0: stackoverflow post
        1: banned from stack overflow

Solution

  • Just change your command_show() function to this, if you don't use dict.items() then you will only get the keys(not both keys and values):

    def command_show(calendar):
        for (date, event) in calendar.items():
            print(date+':')
            for i in enumerate(event):
                print('    '+str(i[0])+': '+i[1])
    

    Output:

    2015-10-29:
        0: Python class
        1: Change oil in blue car
    2015-10-12:
        0: Eye doctor
        1: lunch with sid
    

    About why am I doing this:

    for i in enumerate(event):
        print('    '+str(i[0])+': '+i[1])
    

    As you can see, I'm using enumerate() function here. From the document:

    Return an enumerate object. iterable must be a sequence, an iterator, or some other object which supports iteration.
    The __next__() method of the iterator returned by enumerate() returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over iterable.

    So it will return something like [(0, 'Python class'), (1, 'Eye doctor'), (2, 'lunch with sid')] if the evernt is ['Python class', 'Eye doctor', 'lunch with sid'].

    Now we have [(0, 'Python class'), (1, 'Eye doctor'), (2, 'lunch with sid')], when we use for loop on it like for i in enumerate(event), i will be (0, 'Python class') at the first loop, and (1, 'Eye doctor') at the second loop, etc.

    And then, if you want to print something like 0: Python class(there is some spaces in front of the sting), we need manually put the spaces like ' '+(+ can join strings here, for example, 'foo'+'bar' is foobar).

    Then, because i is a tuple, I'm using slice. i[0] can get the first element in that tuple, i[1] can get the second, etc.

    Because i[0] is a integer, and we can't just do something like 0 + 'foobar'(will raise TypeError: unsupported operand type(s) for +: 'int' and 'str'). So we need use str() function to covert it to string. And then...maybe you'll understand.


    Also you can do something like:

    for num, event in enumerate(event):
        print('    '+str(num), event, sep=': ')
    

    More clear? for num, event in enumerate(event) will give something like num = 0, evert = 'Python class' at the first loop, and...as I said.

    About sep, you could check the document for more details.