【问题标题】:Compare any number of dates in list inside a dictionary比较字典中列表中任意数量的日期
【发布时间】:2018-09-13 18:30:24
【问题描述】:

我有一个这样的日期字典(这里的键与其他一些工作相关,需要考虑):

{2: ['8-12-2012', '9-12-2012', '7-12-2012],
 5: ['10-12-2012', '11-12-2012'],
 7: ['13-12-2012']}

现在,我想在每个列表中找到最早的日期。最后,我需要找出最早的日期,并返回那个日期和密钥。

如果我在这里手动完成我想要做的事情:

**key 2**, `7-12-2012` is the earliest.
**key 5**, `10-12-2012` is the earliest.
**key 7**, `13-12-2012` is the earliest.

7-12-2012 是最早的日期,所以我应该返回2

注意事项:

  1. 字典中的数据是在运行时动态创建的。
  2. 字典中的列表不是固定长度的。

这是我尝试过的,但只比较两个日期:

...
...
# this value would be dynamically set during runtime
expiryDates[item] = {2: ['8-12-2012', '9-12-2012', '7-12-2012], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}

datesInBox = []
dict_earliest_expiration = defaultdict(list)

for n in expiryDates:
    datesInBox = expiryDates[n] # when n = 2; datesInBox = ['8-12-2012', '9-12-2012']
    d1 = time.strptime(datesInBox[0], "%d-%m-%Y")
    d2 = time.strptime(datesInBox[1], "%d-%m-%Y")
    if d1 < d2:
        dict_earliest_expiration[n] = d1
    else:
        dict_earliest_expiration[n] = d2

任何帮助将不胜感激。

【问题讨论】:

    标签: python list date dictionary


    【解决方案1】:

    您可以将所有字符串转换为日期,然后使用min 函数:

    import time
    
    data = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
    d2 = {k: [time.strptime(e, "%d-%m-%Y") for e in v] for k, v in data.items()}
    print(min(d2, key=lambda e: min(d2[e])))
    

    输出

    2
    

    作为替代方案,您可以预先计算字典每个键的最小值:

    data = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
    d2 = {k: min(time.strptime(e, "%d-%m-%Y") for e in v) for k, v in data.items()}
    print(min(d2, key=lambda e: d2[e]))
    

    输出

    2
    

    最后,您可以迭代键值对,而不是遍历键:

    data = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
    d2 = {k: min(time.strptime(e, "%d-%m-%Y") for e in v) for k, v in data.items()}
    print(min(d2.items(), key=lambda t: t[1])[0])
    

    输出

    2
    

    【讨论】:

      【解决方案2】:

      遍历您的 dict 或直接传递密钥。将列表转换为熊猫系列并排序

      import pandas as pd
      d={2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
      
      for key,value in d.items():
          print(key,pd.to_datetime(pd.Series(value)).sort_values().iloc[0])
      

      输出

      (2, Timestamp('2012-07-12 00:00:00'))
      (5, Timestamp('2012-10-12 00:00:00'))
      (7, Timestamp('2012-12-13 00:00:00'))
      

      如果您只关心日期

      for key,value in d.items():
          print(key,pd.to_datetime(pd.Series(value)).dt.date.sort_values().iloc[0])
      

      输出:

      (2, datetime.date(2012, 7, 12))
      (5, datetime.date(2012, 10, 12))
      (7, datetime.date(2012, 12, 13))
      

      按照给出的例子表示日期

      for key,value in d.items():
          print('key: {}, Earliest Date: {} '.format(key,pd.to_datetime(pd.Series(value)).dt.date.sort_values().iloc[0].strftime("%m-%d-%Y")))
      

      输出:

      key: 2, Earliest Date: 07-12-2012 
      key: 5, Earliest Date: 10-12-2012 
      key: 7, Earliest Date: 12-13-2012 
      

      【讨论】:

        【解决方案3】:

        我会慢慢解决这个问题,这样你就可以看到这个过程。一、反转dict:以时间为key,前一个key为value:

        exp = {2: ['8-12-2012', '9-12-2012', '7-12-2012'], 5: ['10-12-2012', '11-12-2012'], 7: ['13-12-2012']}
        rev = []
        
        for key, val_list in exp.items():
            for val in val_list:
                rev[time.strptime(val, "%d-%m-%Y")] = key
        

        清理表示,rev 现在是

        {
            time.struct_time(tm_year=2012, tm_mon=12, tm_mday=13): 7, 
            time.struct_time(tm_year=2012, tm_mon=12, tm_mday= 8): 2, 
            time.struct_time(tm_year=2012, tm_mon=12, tm_mday= 7): 2, 
            time.struct_time(tm_year=2012, tm_mon=12, tm_mday= 9): 2, 
            time.struct_time(tm_year=2012, tm_mon=12, tm_mday=11): 5, 
            time.struct_time(tm_year=2012, tm_mon=12, tm_mday=10): 5
        }
        

        现在最简单的就是打印密钥了:

        >>> rev[min(rev)]
        2
        

        如果您愿意,可以将其折叠成一个 dict 理解和一个​​简单的调用。

        【讨论】:

        • 我不断收到“NameError: name 'rev' is not defined”。尝试谷歌搜索但没有结果。是否有超出 exp 值的东西?
        • 我切断了初始化行。我很抱歉。现已修复。
        猜你喜欢
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-05
        • 2015-07-28
        • 1970-01-01
        • 2017-12-20
        • 2017-12-19
        相关资源
        最近更新 更多