28

我有一个列表,其中包含字符串格式的数字和字母。

mylist=['1','orange','2','3','4','apple']

我需要拿出一个只包含数字的新列表:

mynewlist=['1','2','3','4']

如果我有办法检查列表中的每个项目是否可以转换为整数,我应该能够通过执行以下操作来提出我想要的内容:

for item in mylist:
    if (check item can be converted to integer):
        mynewlist.append(item)

如何检查字符串是否可以转换为整数?或者有没有更好的方法来做到这一点?

4

4 回答 4

46

尝试这个:

mynewlist = [s for s in mylist if s.isdigit()]

文档

str.isdigit()

如果字符串中的所有字符都是数字并且至少有一个字符,则返回 true,否则返回 false。

对于 8 位字符串,此方法取决于区域设置。


正如评论中所指出的,isdigit()返回True并不一定表示可以通过int()函数将字符串解析为int,返回False也不一定表示不能。不过,上述方法应该适用于您的情况。

于 2013-06-04T00:58:00.717 回答
14

快速、简单,但可能并不总是正确的:

>>> [x for x in mylist if x.isdigit()]
['1', '2', '3', '4']

如果您需要获取数字,则更传统:

new_list = []
for value in mylist:
    try:
        new_list.append(int(value))
    except ValueError:
        continue

注意:结果有整数。如果需要,将它们转换回字符串,将上面的行替换为:

try:
    new_list.append(str(int(value)))
于 2013-06-04T00:58:54.170 回答
10

您可以使用异常处理,因为它str.digit仅适用于整数,并且也可能因以下情况而失败:

>>> str.isdigit(' 1')
False

使用生成器函数:

def solve(lis):                                        
    for x in lis:
        try:
            yield float(x)
        except ValueError:    
            pass

>>> mylist = ['1','orange','2','3','4','apple', '1.5', '2.6']
>>> list(solve(mylist))                                    
[1.0, 2.0, 3.0, 4.0, 1.5, 2.6]   #returns converted values

或者你可能想要这个:

def solve(lis):
    for x in lis:
        try:
            float(x)
            return True
        except:
            return False
...         
>>> mylist = ['1','orange','2','3','4','apple', '1.5', '2.6']
>>> [x for x in mylist if solve(x)]
['1', '2', '3', '4', '1.5', '2.6']

或使用ast.literal_eval,这将适用于所有类型的数字:

>>> from ast import literal_eval
>>> def solve(lis):
    for x in lis:
        try:
            literal_eval(x)
            return True
        except ValueError:   
             return False
...         
>>> mylist=['1','orange','2','3','4','apple', '1.5', '2.6', '1+0j']
>>> [x for x in mylist if solve(x)]                               
['1', '2', '3', '4', '1.5', '2.6', '1+0j']
于 2013-06-04T01:00:12.160 回答
6

检查是否可以转换为 an 的常用方法int是 to tryit 并查看,遵循EAFP原则:

try:
    int_value = int(string_value)
except ValueError:
    # it wasn't an int, do something appropriate
else:
    # it was an int, do something appropriate

所以,在你的情况下:

for item in mylist:
    try:
        int_value = int(item)
    except ValueError:
        pass
    else:
        mynewlist.append(item) # or append(int_value) if you want numbers

在大多数情况下,围绕一些mynewlist.append(item)以 但是在这里,你不能,因为没有办法将/放入表达式中。mapfiltertryexcept

但是如果你把它包装在一个函数中,你可以:

def raises(func, *args, **kw):
    try:
        func(*args, **kw)
    except:
        return True
    else:
        return False

mynewlist = [item for item in mylist if not raises(int, item)]

……或者,如果您愿意:

mynewlist = filter(partial(raises, int), item)

以这种方式使用它更清洁:

def raises(exception_types, func, *args, **kw):
    try:
        func(*args, **kw)
    except exception_types:
        return True
    else:
        return False

这样,您可以将您期望的异常(或异常元组)传递给它,这些异常将返回True,但如果引发任何意外异常,它们将传播出去。所以:

mynewlist = [item for item in mylist if not raises(ValueError, int, item)]

......会做你想做的,但是:

mynewlist = [item for item in mylist if not raises(ValueError, item, int)]

... 会提高 a TypeError,因为它应该。

于 2013-06-04T02:35:30.403 回答