从字符串列表中删除整数

Posted

技术标签:

【中文标题】从字符串列表中删除整数【英文标题】:Removing integers from a list of list of strings 【发布时间】:2016-04-03 12:14:00 【问题描述】:

我有一个要删除整数的字符串列表列表

[[[u'HH', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]]

以上列表应该返回

[[[u'HH', u'AH', u'L', u'OW'], [u'HH', u'EH', u'L', u'OW']]]

我尝试过使用过滤器

filter(lambda i: not str.isdigit(i), phoneseqList[0])

但这似乎不起作用

【问题讨论】:

你能提供你使用的真实代码吗? filter 本身不会告诉我们您是否未能以其他方式正确使用它;已经存在明显的问题(phoneseqList[0] 可能是错误的,因为单一级别的索引仍在使用listlistunicode)。另外,需要明确的是,这是 Python 2 还是 Python 3 代码?字符串上的 u 前缀使 Py2 成为可能,但在 Py2 和 Py3 中都是合法的。 【参考方案1】:

如果数字总是在最后,你可以使用str.rstrip

>>> phone_seq_list = [['HH', 'AH0', 'L', 'OW1'], ['HH', 'EH0', 'L', 'OW1']]
>>> [[s.rstrip('0123456789') for s in l] for l in phone_seq_list]
[['HH', 'AH', 'L', 'OW'], ['HH', 'EH', 'L', 'OW']]

【讨论】:

请注意,这假设数字字符只会出现在每个字符串的尾部,这恰好是给定示例的情况,但未在问题中指定(仅提及删除整数)。 你说得对,我只是修改了我的答案来解释这一点。【参考方案2】:

您当前正在查看第一个嵌套list 中的每个字符串,它本身就是list,因此缺少isdigit() 方法。您需要处理每个字符。

phoneseqList = [[[u'HH', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]]
newlist = [[[''.join(element for element in item if not element.isdigit()) for item in sublist] for sublist in phoneseqList[0]]]

结果:

>>> newlist
[[[u'HH', u'AH', u'L', u'OW'], [u'HH', u'EH', u'L', u'OW']]]

【讨论】:

【参考方案3】:

看到数字位于单词的末尾,并且您想要的每个项目最多 2 个字符,您可以对字符串进行切片以仅提取前两个字符。这会遗漏最后的数字。

l = [[u'HH', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]

newL = []
for sublist in l:
    tempL = []
    for item in sublist:
        tempL.append(item[:2])
    newL.append(tempL)
print newL

【讨论】:

【参考方案4】:

对于任意嵌套的字符串列表,这里有一个递归解决方案,它将从所有字符串中删除任何数字

def remove_digits(i):
    if isinstance(i, list):
        return [remove_digits(j) for j in i]
    else:
        return ''.join(j for j in i if not j.isdigit())

例子

>>> l = [[[u'HH', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]]
>>> remove_digits(l)
[[['HH', 'AH', 'L', 'OW'], ['HH', 'EH', 'L', 'OW']]]

编辑 要为每个字符串添加扩展名,您可以执行相同的想法

def add_ext(i, ext):
    if isinstance(i, list):
        return [add_ext(j, ext) for j in i]
    else:
        return i + ext

所以你可以说

>>> add_ext(l, '.jpeg')

【讨论】:

在将内容附加到列表时,同样的逻辑是否有效?我现在想为每个元素添加一个“.jpeg”字符串,但我不确定 join 方法在 else 中做了什么 @NeptuneGamer 是的,同样的想法也适用,请参阅我的编辑。 如果您愿意,您也可以一次完成所有操作,所以else 的情况可能是''.join(blah) + ext 为什么不return re.sub("\d+","",i)【参考方案5】:

进一步嵌套循环:

from itertools import filterfalse  # ifilterfalse on Python 2

for sublist1 in toplist:
    for sublist2 in sublist1:
        for i, s in enumerate(sublist2):
           sublist2[i] = ''.join(let for let in s if not let.isdigit())

是的,您可以使用所有嵌套列表推导中最糟糕的一种来创建一个新的 listlistlists 并替换现有的,但在这种情况下,它更直接/可读使用显式循环改变现有的list。如果您以后需要未修改的版本,您可以随时copy.deepcopy原始***list

【讨论】:

【参考方案6】:

这应该可以解决您的问题:

def strip_digits(text):
    return ''.join([c for c in text if not c.isdigit()])


def filter_list(outer):
    return [[strip_digits(i) for i in inner] for inner in outer]

如果您喜欢 TDD 方式,请使用随附的单元测试 :)

class FilterListTest(unittest.TestCase):

    def test_filter_list(self):
        # Arrange
        actual = [[u'HH', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]
        expected = [[u'HH', u'AH', u'L', u'OW'], [u'HH', u'EH', u'L', u'OW']]

        # Act & Assert
        self.assertEquals(filter_list(actual), expected)

【讨论】:

【参考方案7】:

您可以使用str.translate 删除数字:

l = [[[u'HH2', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]]

tbl = ord(d): u"" for d in u"0123456789"
for sub in l:
    sub[:] = [[s.translate(tbl) for s in w] for w in sub]

输出:

[[[u'HH', u'AH', u'L', u'OW'], [u'HH', u'EH', u'L', u'OW']]]

如果你想任意嵌套:

l = [[[u'HH2', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]]

def rem_d(l, tbl):
    if isinstance(l, list):
        return [rem_d(ele, tbl) for ele in l]
    return l.translate(tbl)



tbl = ord(d): u"" for d in u"0123456789"


print(list(rem_d(l, tbl)))

输出:

[[[u'HH', u'AH', u'L', u'OW'], [u'HH', u'EH', u'L', u'OW']]]

翻译会比遍历每个数字快很多:

In [13]: l = [[[u'HH2', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]]

In [14]: l = [l[0] for _ in range(100000)]

In [15]: timeit rem_d(l, tbl)
1 loops, best of 3: 777 ms per loop

In [16]: timeit remove_digits(l)
1 loops, best of 3: 1.83 s per loop
In [17]: remove_digits(l) == rem_d(l,tbl)
Out[17]: True

【讨论】:

【参考方案8】:

我同意@CoryKramer 关于递归实现的观点(除非情况始终是列表列表的列表)。以下实现类似,仅在必要时保留 unicode 编码。

import re

lst = [[[u'HH', u'AH0', u'L', u'OW1'], [u'HH', u'EH0', u'L', u'OW1']]]

def removeDigits(lst):
    for i,l in enumerate(lst):
        if isinstance(l, list):
            removeDigits(l)
        else:
            lst[i] = re.sub('[0-9]+','', l)

removeDigits(lst)
print lst

输出

[[[u'HH', u'AH', u'L', u'OW'], [u'HH', u'EH', u'L', u'OW']]]

【讨论】:

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

节点已插入,但输入的第一个节点已从列表中删除

python列表(list)+索引切片+修改+插入+删除+range函数生成整数列表对象

如何从字符串类型数组中删除整数?

从字符串数组中获取整数列表

如何从字符串列表中删除引号并将其再次存储为列表..?

如何从整数中删除最小值并在不使用字符串的情况下返回其余数字[关闭]