Python将函数列表应用于包含无值的项列表

时间:2015-02-22 05:03:42

标签: python list list-comprehension

如果我有一个数据项列表,我想转换类型

例如:

row = (u'2013-13-04 00:00:00',
     u'P1',
     u'BRT64510',
     u'CHUCKLES MOTOR COMPANY',
     u'123',
     None,
     u'2345',
     u'100000',
     u'150000000',
     None,
     u'100000',
     None,
     u'123345',
     u'1234567',
     u'122445',
     None)

和转换公式列表,例如:

import datetime
dt = datetime.datetime
st = lambda x: dt.strptime(x,'%Y-%m-%d %H:%M:%S')
f = lambda x: float(x)
s = lambda x: str(x)

conversion = [st, s, s, s, f, f, f, f, f, f, f, f, f, f, f, f]

我试图应用以下内容:

result =[func(value) for func,value in zip(conversion,row)]

但我当然会收到NULL : None值的错误。

是否有快速修复,允许我将一个函数列表应用于项目列表,同时将空值保留为空?此清理将应用于大量记录列表,因此我不知道哪些值将提前为空。

感谢

6 个答案:

答案 0 :(得分:3)

result = [func(value) if value is not None else None
          for func, value in zip(conversion, row)]

答案 1 :(得分:1)

只需更改f功能,就像这样

f = lambda x: float(x) if isinstance(x, unicode) else x

或者这个

f = lambda x: float(x) if x is not None else x

现在,如果输入的类型为unicode(或第二种情况,如果x不是None),则会在其上调用float

在您的情况下,您只需避开lambda功能,然后制作

conversion = [st, str, str, str, float, ...]

然后在列表理解中包含条件,就像这个

[val if value is None else func(val) for func, val in zip(conversion, row)]

注意:您的日期格式不正确,您可能需要更改格式,例如

dt.strptime(x,'%Y-%d-%m %H:%M:%S')

以便匹配

'2013-13-04 00:00:00'

答案 2 :(得分:1)

另一种方法是为identity值添加NULL函数。

>>> i = lambda x: x
>>> conversion = [st, s, s, s, f, i, f, f, f, i, f, i, f, f, f, i]
>>> result = [func(value) for func, value in zip(conversion, row)]

顺便说一句,您的日期时间转换格式不正确。它应该如下:

st = lambda x: dt.strptime(x,'%Y-%d-%m %H:%M:%S') 

答案 3 :(得分:1)

您还可以考虑itertools.starmap()此功能。

让我们假设你创建一个函数,它接受一个函数和一个参数,并返回函数返回的值,

def myApply(f, v): 
    try: return f(v)
    except: return None

然后,您可以使用starmap按顺序将这些函数应用于值:

import itertools as itt
result = itt.starmap( myApply, zip( conversion, row ) )

try - except方法可以捕获各种问题。但是,它会静默只将结果转换为None。如果您不想要这种行为,可以考虑将except选项更改为更有意义的内容......

答案 4 :(得分:1)

result =[None if isinstance(value, type(None)) else func(value) for func,value in zip(conversion,row)]

答案 5 :(得分:1)

使用具有转换功能的try / except结构:

def conv(f, x):
    try:
        return f(x)
        # TypeError catches float(None)
        # add ValueError if you might get float('abc') for example...
    except TypeError: 
        return x

result =[conv(func, value) for func,value in zip(conversion,row)]   

然后你接近完美的工作(一旦你纠正了dt.strstrptime(x,'%Y-%d-%m %H:%M:%S')):

import datetime
dt = datetime.datetime
st = lambda x: dt.strptime(x,'%Y-%d-%m %H:%M:%S')
f = lambda x: float(x)
s = lambda x: str(x)

conversion = [st, s, s, s, f, f, f, f, f, f, f, f, f, f, f, f]    

def conv(f, x):
    try:
        return f(x)
    except (TypeError, ValueError):
        return x

result =[conv(func, value) for func,value in zip(conversion,row)]    
print result    

打印:

[datetime.datetime(2013, 4, 13, 0, 0), 'P1', 'BRT64510', 'CHUCKLES MOTOR COMPANY', 123.0, None, 2345.0, 100000.0, 150000000.0, None, 100000.0, None, 123345.0, 1234567.0, 122445.0, None]