从列表中的元组中删除空字符串

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,生成器表达式将生成xint(x),具体取决于所讨论的x 是否为字符串形式的数字。 (试图将非数字字符串转为整数会导致异常。)

对于lst 中的每个元组_,生成器会创建一个新的、相同的元组,除了过滤掉空的假字符串并将任何数字字符串转换为ints。

以上代码等价于:

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 包裹在它周围,你会得到指定的输出。

以上是关于从列表中的元组中删除空字符串的主要内容,如果未能解决你的问题,请参考以下文章

如果子字符串存在,则从元组中删除项目

从字符串列表中删除空字符串

如何删除python列表列表中的''(空字符串)?

从列表中的元组替换字符串

从列表中删除空字符串(Spark Dataframe)[重复]

如何删除一些额外的元组和列表并在python中的字符串之间打印一些额外的东西?