现在我有三个从RE findall函数生成的列表,我试图从列表中的元组中删除一些空字符串。并且数字也应该在过程中转换为整数:
GOT:[('', '', '1', '1')]
预期:[(1, 1)]
得到:[('', '', '20', '500'), ('21', 'failed', '', '')]
预期:[(20, 500), (21, 'failed')]
得到:[('3', 'failed', '', ''), ('', '', '48', '23'), ('', '', '96', '0')]
预期:[(3, 'failed'), (48, 23), (96, 0)]
有什么想法吗?
答案 0 :(得分:5)
使用元组构造函数的嵌套列表解析:
>>> lst = [('', '', '20', '500'), ('21', 'failed', '', '')]
>>> [(tuple(int(x) if x.isdigit() else x for x in _ if x)) for _ in lst]
[(20, 500), (21, 'failed')]
对于_
中的每个元组(lst
),构造一个带有生成器表达式的tuple
。单独的元组构造函数如下:
tuple(int(x) if x.isdigit() else x for x in _ if x)
这似乎令人困惑,但我会把它分解。对于元组x
中的每个字符串_
(lst
中的元组),构造一个元组。 if x
检查字符串是否为空。 (如果字符串x
为空,x
为false。)if x
,生成器表达式将生成x
或int(x)
,具体取决于x
问题是字符串形式的数字。 (尝试将非数字字符串转换为整数将导致异常。)
对于_
中的每个元组lst
,生成器创建一个新的,相同的元组,除了空的假字符串被过滤掉,任何数字字符串都转换为int
s。
以上代码相当于:
new_lst = []
for _ in lst: # For each tuple in lst
for x in _: # For each string in tuple
temp_tuple = ()
if x: # Only add to tuple if string is not empty
if x.isdigit(): # If x is a digit in string form
temp_tuple += (int(x),) # Convert to int
else:
temp_tuple += (x,) # Keep string
new_lst.append(temp_tuple)
答案 1 :(得分:3)
这个怎么样:
def sanitize(t):
for i in t:
try:
yield int(i)
except ValueError:
yield i
inputs = [('3', 'failed', '', ''), ('', '', '48', '23'), ('', '', '96', '0')]
map(tuple, map(sanitize, [filter(None, i) for i in inputs]))
输出:
[(3, 'failed'), (48, 23), (96, 0)]
filter
是一个对序列进行操作的函数,只返回“truthy”元素。空字符串是假的。 Map是另一个函数,它接受一个序列并通过给定的函数运行该序列中的每个元素。在这种情况下,函数sanitize
将字符串转换为int(如果可以),否则只返回字符串。
我们在yield
函数中使用return
而不是sanitize
作为将另一个序列返回到下一个地图函数的简单方法。或者,我们可以在函数内部构建一个列表并返回它。