通过二维字典中的两个字段对python对象进行分组

时间:2014-02-08 12:18:53

标签: python list dictionary reference grouping

我有一个python类Episode,它有两个字段:seasonnumber。我在Episode中有一个列表ob episode_list个对象。该列表按季节排序,然后按剧集排序。在下面的示例中,数据按此顺序创建。 我想要做的是:我想创建一个Season对象的字典。每个Season对象还有一个字典作为名为episodes的字段。该词典应包含具有此季节数的所有Episode个对象。 在下面的最小示例的末尾,我打印分组数据,结果是:

S3E1
S3E2
S3E3
S3E1
S3E2
S3E3
S3E1
S3E2
S3E3

这是错误的(根据我创建的数据)应该是:

S1E1
S1E2
S1E3
S2E1
S2E2
S2E3
S3E1
S3E2
S3E3

# required classes
class Episode:
    def __init__(self, season, number):
        self.season = season
        self.number = number


class Season:
    episodes = {}

    def __init__(self, number):
        self.number = number

# create episode data
episode_list = []
for i in range(3):
    episode_list.append(Episode(1, i+1))

for i in range(3):
    episode_list.append(Episode(2, i+1))

for i in range(3):
    episode_list.append(Episode(3, i+1))

# group episodes by seasons
seasons = {}
for episode in episode_list:
    for season_number in range(1, 4):
        season = Season(season_number)
        for episode in episode_list:
            if episode.season == season_number:
                season.episodes[episode.number] = episode
        seasons[season_number] = season

# print result
for sn, s in seasons.items():
    for en, e in s.episodes.items():
        print "S" + str(e.season) + "E" +  str(e.number)

2 个答案:

答案 0 :(得分:1)

这里你已经为剧集制作了一个类属性

class Season:
    episodes = {}

    def __init__(self, number):
        self.number = number

这意味着所有季节实例共享相同的dict

您应该将其设为实例属性

class Season:    
    def __init__(self, number):
        self.episodes = {}
        self.number = number

答案 1 :(得分:0)

这是你的问题:

class Season:
    episodes = {}

episodes是一个类属性。所有Season共享相同的episodes字典。您需要使episodes成为实例属性,如下所示:

def __init__(self, number):
    self.episodes = {}
    self.number = number

你拥有所有其他属性,所以这个属性是一个类属性而不是实例属性有点奇怪。

另外,请注意循环字典:

for sn, s in seasons.items():
    for en, e in s.episodes.items():

不保证提供任何特定订单。您可能会在第1季之前到达第2季。如果重要,您可以使用sorted按顺序循环:

for sn, s in sorted(seasons.items()):
    for en, e in sorted(s.episodes.items()):