4

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
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Sinoda
  • 245
  • 1
  • 3
  • 9

3 Answers3

4

for ... in calendar: will only loop over the keys in the dictionary. You need to call .items() to get both keys and values:

def command_show(calendar):
    for date, events in calendar.items():
        print(date, enumerate(events))

You can also simplify command_add by using .setdefault() method:

def command_add(date, event, calendar):
    calendar.setdefault(date, []).append(event)
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
2

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.

Community
  • 1
  • 1
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
  • hey this worked really well but i just wanted to clarify something for my understanding. when u iterate the for loop thru i in enumerate(event) . how does str(i[0]) and + i[1], the first 1 add's the numbers to enumerate the list (str(i[0]) and the second one i[1] gets all the events i just don't know how that interaction works. because i want to be able to delete something from the list as well so im trying to understand what i would need to access to delete a specifc entry at a given date – Sinoda Nov 01 '15 at 20:55
  • more specifically why did u put a [0] and [1] in brackets what does that do exactly – Sinoda Nov 01 '15 at 21:11
  • this was brilliant thanks for the well thought out reply i appreciate it really helps me understand – Sinoda Nov 02 '15 at 00:05
0

You can use a defaultdict which which take care of that if check for you; and loop through the calendar.iteritems() so that you get a tuple of key,value on each iteration.

from collections import defaultdict

calendar = defaultdict(list)

def command_add(date, event, calendar):
    calendar[date].append(event)

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)

for date, events in calendar.iteritems():
    print(date)
    for event in events:
        print('\t{}'.format(event))
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284