如何忽略无效输入或在排序函数中添加try除代码?

时间:2015-06-22 10:02:27

标签: python lambda sorted

我想根据日期对字典列表进行排序。

以下代码工作正常,我的数据格式是固定的,即dd / mm / yyyy

代码:

[{'date': '10/10/2015'},
 {'date': '11/10/2015'},
 {'date': '01/01/2015'},
 {'date': '10/12/2014'},
 {'date': '01/01/2014'},
 {'date': '2015'}]

In [20]: a.pop()
Out[20]: {'date': '2015'}

In [21]: sorted(a, key=lambda x: datetime.datetime.strptime(x['date'], "%d/%m/%Y"), reverse=False)
Out[21]: 
[{'date': '01/01/2014'},
 {'date': '10/12/2014'},
 {'date': '01/01/2015'},
 {'date': '10/10/2015'},
 {'date': '11/10/2015'}]

但是我的日期值也与dd / mm / yyyy格式不匹配。 获得以下例外:

代码2:

In [22]: a.append({"date":"2015"})

In [23]: sorted(a, key=lambda x: datetime.datetime.strptime(x['date'], "%d/%m/%Y"), reverse=False)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-23-abd07eed54eb> in <module>()
----> 1 sorted(a, key=lambda x: datetime.datetime.strptime(x['date'], "%d/%m/%Y"), reverse=False)

<ipython-input-23-abd07eed54eb> in <lambda>(x)
----> 1 sorted(a, key=lambda x: datetime.datetime.strptime(x['date'], "%d/%m/%Y"), reverse=False)

/usr/lib/python2.7/_strptime.py in _strptime(data_string, format)
    323     if not found:
    324         raise ValueError("time data %r does not match format %r" %
--> 325                          (data_string, format))
    326     if len(data_string) != found.end():
    327         raise ValueError("unconverted data remains: %s" %

ValueError: time data '2015' does not match format '%d/%m/%Y'

In [24]: 

如何在sorted函数中处理此类输入

2 个答案:

答案 0 :(得分:2)

我们的数据:

In [51]: a = [{'date': '10/10/2015'},
   ....:  {'date': '11/10/2015'},
   ....:  {'date': '01/01/2015'},
   ....:  {'date': '10/12/2014'},
   ....:  {'date': '01/01/2014'},
   ....:  {'date': '2015'}]

首先从a

中删除错误的日期
In [52]: a = [i for i in a if len(i['date'])>9]

第二

In [53]: sorted(a, key=lambda x: datetime.datetime.strptime(x['date'], "%d/%m/%Y"), reverse=False)
Out[53]: 
[{'date': '01/01/2014'},
 {'date': '10/12/2014'},
 {'date': '01/01/2015'},
 {'date': '10/10/2015'},
 {'date': '11/10/2015'}]

您可以将其写入一行:

sorted([i for i in a if len(i['date'])>9], key=lambda x: datetime.datetime.strptime(x['date'], "%d/%m/%Y"), reverse=False)

答案 1 :(得分:2)

一个选项是处理键功能中的异常:

def custom_sort(x):
    try:
        return datetime.datetime.strptime(x['date'], "%d/%m/%Y")
    except ValueError:
        # do something else if the date format is different
    except KeyError:
        # do something else if there is no 'date' key in x
        # ...

sorted(a, key=custom_sort)

或者您可以使用if-else构造在应用日期时间函数之前将数据转换为正确的格式...

编辑:这里有两个更实用的选项:

a = [{'date': '05/06/2017'}, {'ff': 2016}, {'date': 2015}, {'date': '05/06/2014'}, 'ff']

def sort_by_converting_to_strings(x):
    try:
        return str(datetime.datetime.strptime(x['date'], "%d/%m/%Y"))
    except (KeyError, ValueError, TypeError):
        try:
            return str(x['date'])
        except (KeyError, TypeError):
                return str(x)
print sorted(a, key=sort_by_converting_to_strings)
# [{'date': '05/06/2014'}, {'date': 2015}, {'date': '05/06/2017'}, 'ff', {'ff': 2016}]


def validate(x):
    try:
        datetime.datetime.strptime(x['date'], "%d/%m/%Y")
        return True
    except Exception:
        return False
print sorted([i for i in a if validate(i)])
# [{'date': '05/06/2014'}, {'date': '05/06/2017'}]

当然,您可以结合使用这些方法来获得适合您特定用例的解决方案......