如何遍历元组字典?

时间:2017-08-08 16:31:41

标签: python python-2.7 datetime dictionary tuples

我在字典month,day中存储了以下seasons元组:

seasons = {
    'S1': (
        ((1, 10),(5, 31))
    ),
    'S2': (
        ((9, 1),(1, 9))
    ),
    'S3': (
        ((6, 1),(9, 30))
    )
}

我想检查日期时间dt所在的日期间隔,并相应地指定名称S1S2S3

我尝试这样做,但startend似乎是数字而不是元组。

    def getSeason(dt):
        season = None    
        for t, ranges in seasons.items():
            for start, end in ranges:
                if date(dt.year,start(0),start(1)) <= dt.date() <= date(dt.year,end(0),end(1)):
                    season = t
                    break
            if season is not None:
                break
        return season

3 个答案:

答案 0 :(得分:2)

很少有问题,我看到你的代码 -

  1. 你似乎假设你有一个元组元组的元组,但你实际上有一个tupe元组,因为当你试图创建一个元素的元组时,你需要跟随元素一个{ {1}},否则python会将其解释为用于分组的括号。示例 -

    ,

    简单来说,

    a = ((1,2),)
    
  2. 其次,在访问元组值时,您应该使用a = (1,) ,而不是start[0],因为后者尝试将其称为函数,start(0)作为参数

  3. 你的逻辑不考虑赛季开始的时间是一年,而赛季结束的时间是明年。

  4. 所以季节看起来像 -

    0

    对原始seasons = { 'S1': ( ((1, 10),(5, 31)), ), 'S2': ( ((9, 1),(1, 9)), ), 'S3': ( ((6, 1),(9, 30)), ) } 功能进行细微更改,以使您的案例有效 -

    getSeason()

    上面的方法可行,但是你并不需要为你的用例提供元组元组元组,你可以改变def getSeason(dt): season = None for t, ranges in seasons.items(): for start, end in ranges: if start[0] <= end[0] or (start[0] == end[0] and start[1] <= end[1]): if date(dt.year,start[0],start[1]) <= dt.date() <= date(dt.year,end[0],end[1]): season = t break else: if (date(dt.year,start[0],start[1]) <= dt.date() <= date(dt.year+1,end[0],end[1])) or (date(dt.year-1,start[0],start[1]) <= dt.date() <= date(dt.year,end[0],end[1])): season = t break if season is not None: break return season 函数中的逻辑来使用元组元组。

答案 1 :(得分:-1)

主要问题是您正在解包元组,从而将int转换为startend。如果删除嵌套循环,您的代码将按预期工作:

from datetime import datetime

seasons = {
    'S1': (
        (1, 10), (5, 31),
    ),
    'S2': (
        (9, 1), (1, 9),
    ),
    'S3': (
        (6, 1), (9, 30),
    )
}


def getSeason(dt):
    for t, (start, end) in seasons.iteritems():
        if start[0] < end[0] and datetime(dt.year, start[0], start[1]) <= dt <= datetime(dt.year, end[0], end[1]):
            return t

        elif (start[0] > end[0] and
                  (datetime(dt.year, start[0], start[1]) <= dt <= datetime(dt.year + 1, end[0], end[1]) or
                   datetime(dt.year - 1, start[0], start[1]) <= dt <= datetime(dt.year, end[0], end[1]))):
            return t

        else:
            continue

    return None

答案 2 :(得分:-1)

尝试以下方法:

from datetime import date

seasons = {
    'S1': (
        ((1, 10),(5, 31))
    ),
    'S2': (
        ((9, 1),(1, 9))
    ),
    'S3': (
        ((6, 1),(9, 30))
    )
}

def getSeason(dt):
    for sname, duration in seasons.items():
        start, end = duration
        start_date = date(dt.year, start[0], start[1])
        end_date = date(dt.year, end[0], end[1])
        if dt < start_date:
            start_date = date(start_date.year - 1, start_date.month, start_date.day)
            end_date = date(end_date.year - 1, end_date.month, end_date.day)
        if end_date < start_date:
            end_date = date(end_date.year+1, end_date.month, end_date.day)
        if start_date <= dt <= end_date:
            return sname
    return None

if __name__ == '__main__':
    s = getSeason(date(1921, 5, 24))
    print s