从列表中的元组中删除空字符串
Posted
技术标签:
【中文标题】从列表中的元组中删除空字符串【英文标题】:Remove empty strings from tuples inside a list 【发布时间】:2014-02-18 22:26:39 【问题描述】:现在我有三个从 RE findall 函数生成的列表,我正在尝试从列表中的元组中删除一些空字符串。在这个过程中,数字也应该转换为整数:
得到:[('', '', '1', '1')]
预期:[(1, 1)]
得到:[('', '', '20', '500'), ('21', 'failed', '', '')]
预期:[(20, 500), (21, 'failed')]
得到:[('3', 'failed', '', ''), ('', '', '48', '23'), ('', '', '96', '0')]
预期:[(3, 'failed'), (48, 23), (96, 0)]
有什么想法吗?
【问题讨论】:
您使用的是哪个正则表达式?为什么不首先使用与空字符串不匹配的字符串,而不是之后将其过滤掉? 我尽力了...但我无法写出不同的正则表达式... 好吧,也许我们可以帮你解决这个问题? mission_report('是,任务 3 失败。完成 48 次袭击:找到目标:23。完成任务 96,找到目标:0') 应该返回 [(3,'failed'), ( 48, 23), (96, 0)])。我为此写的正则表达式是: match=re.findall(r'(?:raid|mission) (\d+) (failed)|(\d+) (?:was )?accomplished.*?found: (\d+ )', s, re.IGNORECASE) 啊,好的,所以总会有两个空的反向引用。我知道了。好吧,让我们按照你的方式做吧……等一下。 【参考方案1】:带有元组构造函数的嵌套列表推导:
>>> 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
为假。)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)
【讨论】:
你们愿意解释一下吗? 它返回 [(500,), ()] @user3238319 您必须使用准确的输入和输出来编辑您的代码。再次在文件开头运行我的代码,它对我来说非常有效。【参考方案2】:这个怎么样:
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
是一个对序列进行操作并仅返回“真实”元素的函数。空字符串是虚假的。 Map 是另一个函数,它接受一个序列并通过给定函数运行该序列中的每个元素。在这种情况下,函数sanitize
可以将字符串转换为 int,否则只返回字符串。
我们在sanitize
函数中使用yield
而不是return
作为将另一个序列返回到下一个映射函数的简单方法。或者,我们可以在函数内部构建一个列表并返回它。
【讨论】:
我在提交之前在shell中对其进行了测试,所以它可以工作。你必须发布你的实际代码让我告诉你出了什么问题。尝试剥离层并找出哪个不工作。调试!对这类事情使用 Python 控制台。 再次仔细检查,将确切的代码复制到终端并运行它。工作正常。如果你愿意,我会重新格式化它以不显示输出。 这是返回地图对象。我猜它与python版本有关。 没错,这是 Python 2,如果你将list
包裹在它周围,你会得到指定的输出。以上是关于从列表中的元组中删除空字符串的主要内容,如果未能解决你的问题,请参考以下文章