Python 将函数列表应用于包含 None 值的项目列表
Python applying a list of functions to a list of items including None values
如果我有一个要转换类型的数据项列表
例如:
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
值方面遇到了错误。
是否有快速修复程序可以让我将函数列表应用于项目列表,同时将空值保留为空值?此清理将应用于大量记录,因此我不知道哪些值会提前为空。
谢谢
result = [func(value) if value is not None else None
for func, value in zip(conversion, row)]
只需更改您的 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'
另一种选择是为 NULL
个值添加 identity
函数。
>>> 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')
这个功能也可以考虑itertools.starmap()
。
让我们假设您创建一个函数,该函数接受一个函数和一个参数以及 returns 函数的值 returns,
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
选项更改为更有意义的内容 ...
result =[None if isinstance(value, type(None)) else func(value) for func,value in zip(conversion,row)]
使用带有转换函数的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]
如果我有一个要转换类型的数据项列表
例如:
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
值方面遇到了错误。
是否有快速修复程序可以让我将函数列表应用于项目列表,同时将空值保留为空值?此清理将应用于大量记录,因此我不知道哪些值会提前为空。
谢谢
result = [func(value) if value is not None else None
for func, value in zip(conversion, row)]
只需更改您的 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'
另一种选择是为 NULL
个值添加 identity
函数。
>>> 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')
这个功能也可以考虑itertools.starmap()
。
让我们假设您创建一个函数,该函数接受一个函数和一个参数以及 returns 函数的值 returns,
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
选项更改为更有意义的内容 ...
result =[None if isinstance(value, type(None)) else func(value) for func,value in zip(conversion,row)]
使用带有转换函数的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]