枚举列表中的列表

enumerating a list in a 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)

我以为这会让我访问日期下的辅助列表并枚举它,但我收到错误消息。

示例:

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

for ... in calendar: 只会遍历字典中的键。您需要调用 .items() 来获取 键和值 :

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

您还可以使用 .setdefault() 方法简化 command_add

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

只要把你的command_show()函数改成这个,如果你不使用dict.items()那么你将得到钥匙(不是钥匙和值):

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

输出:

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

关于我为什么要这样做:

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

如您所见,我在这里使用了 enumerate() 函数。来自文档:

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.

所以如果 evernt['Python class', 'Eye doctor', 'lunch with sid'],它会 return 类似于 [(0, 'Python class'), (1, 'Eye doctor'), (2, 'lunch with sid')]

现在我们有 [(0, 'Python class'), (1, 'Eye doctor'), (2, 'lunch with sid')],当我们像 for i in enumerate(event) 一样在其上使用 for 循环时,i 将在第一个循环中变为 (0, 'Python class'),并且(1, 'Eye doctor') 在第二个循环等

然后,如果你想打印类似0: Python class的东西(sting前面有一些空格),我们需要手动输入空格,比如' '+(+可以在这里连接字符串,例如 'foo'+'bar'foobar)。

然后,因为 i 是一个元组,所以我使用 slicei[0] 可以获得该元组中的第一个元素,i[1] 可以获得第二个,依此类推。

因为i[0]是一个整数,我们不能只做类似0 + 'foobar'的事情(会加注TypeError: unsupported operand type(s) for +: 'int' and 'str')。所以我们需要使用 str() 函数将其转换为字符串。然后……也许你会明白。


你也可以这样做:

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

更清楚? for num, event in enumerate(event) 将在第一个循环中给出类似 num = 0, evert = 'Python class' 的内容,并且...正如我所说。

关于sep,您可以查看the document了解更多详情。

您可以使用 defaultdict 来为您处理 if 检查;并循环遍历 calendar.iteritems() 以便在每次迭代时得到一个 key,value 的元组。

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))