我有一个包含字符串格式的数字和字母的列表。
mylist=['1','orange','2','3','4','apple']
我需要提出一个仅包含数字的新列表:
mynewlist=['1','2','3','4']
如果我有办法检查列表中的每个项目是否可以转换为Integer,我应该能够通过这样的方式得到我想要的东西:
for item in mylist:
if (check item can be converted to integer):
mynewlist.append(item)
如何检查字符串是否可以转换为整数?或者有更好的方法吗?
答案 0 :(得分:31)
试试这个:
mynewlist = [s for s in mylist if s.isdigit()]
来自docs:
<强>
str.isdigit()
强>如果字符串中的所有字符都是数字且至少有一个字符,则返回true,否则返回false。
对于8位字符串,此方法取决于语言环境。
如评论中所述,返回isdigit()
的{{1}}并不一定表示可以通过True
函数将字符串解析为int,并返回int()
并不一定表明它不可能。尽管如此,上述方法应该适用于您的情况。
答案 1 :(得分:12)
快速,简单,但可能并非总是正确:
>>> [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)))
答案 2 :(得分: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']
答案 3 :(得分:4)
检查某些内容是否可以转换为int
的常用方法是try
,并按照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)
结尾的简单代码的循环可以转换为列表理解,生成器表达式或对map
或filter
的调用。但是在这里,你不能,因为没有办法将try
/ except
放入表达式。
但如果你把它包装在一个函数中,你可以:
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)]
...将提升TypeError
,因为它应该。