如何将 intable 字符串列表转换为 int
Posted
技术标签:
【中文标题】如何将 intable 字符串列表转换为 int【英文标题】:How to convert list of intable strings to int 【发布时间】:2012-04-09 19:16:20 【问题描述】:在 Python 中,我想转换一个字符串列表:
l = ['sam','1','dad','21']
并将整数转换为整数类型,如下所示:
t = ['sam',1,'dad',21]
我试过了:
t = [map(int, x) for x in l]
但显示错误。
如何将列表中的所有 intable 字符串转换为 int,而将其他元素保留为字符串?
我的列表可能是多维的。一种适用于通用列表的方法会更好:
l=[['aa','2'],['bb','3']]
【问题讨论】:
请注意,[map(int, x) for x in l]
会尝试将每个字符串逐个字符地转换为整数的列表。您的意思可能是map(int, l)
或[int(x) for x in l]
。
[int(x) for x in l]
将抛出 ValueError
s 用于非数字字符串。
map(lambda line: [int(i) if i.isdigit() else i for i in line.split(",")])
- 注意这不考虑负整数。
【参考方案1】:
我会使用自定义函数:
def try_int(x):
try:
return int(x)
except ValueError:
return x
例子:
>>> [try_int(x) for x in ['sam', '1', 'dad', '21']]
['sam', 1, 'dad', 21]
编辑:如果您需要将上述内容应用于列表列表,为什么在构建嵌套列表时不将这些字符串转换为 int? p>
无论如何,如果需要,只是选择如何遍历这样的嵌套列表并应用上面的方法。
这样做的一种方法可能是:
>>> list_of_lists = [['aa', '2'], ['bb', '3']]
>>> [[try_int(x) for x in lst] for lst in list_of_lists]
[['aa', 2], ['bb', 3]]
您显然可以将其重新分配给list_of_lists
:
>>> list_of_lists = [[try_int(x) for x in lst] for lst in list_of_lists]
【讨论】:
@larsmans:嗯……我不知道……我可能被 OPmap()
弄得眼花缭乱。我稍后会更新答案:)
我已经大胆地为你做这件事了。
@RikPoggi 请查看已编辑的部分,我正在尝试该类型的列表
@sum2000:你应该从一开始就说明 :) 无论如何,只需遍历你的 list_of_list 并将上述方法应用于每个子列表。【参考方案2】:
我会创建一个生成器来做到这一点:
def intify(lst):
for i in lst:
try:
i = int(i)
except ValueError:
pass
yield i
lst = ['sam','1','dad','21']
intified_list = list(intify(lst))
# or if you want to modify an existing list
# lst[:] = intify(lst)
如果您希望它适用于列表列表,只需:
new_list_of_lists = map(list, map(intify, list_of_lists))
【讨论】:
思路是对的,但是实现不是很优雅;str
-to-int
转换和迭代应该像 Rik Poggi 的回答那样真正分开。
@larsmans 我不同意。我基于这个问题假设这只会用于序列,那么为什么需要map
的额外步骤?并非所有内容都必须以函数式编程风格编写。 (另外,纯粹作为奖励,这在 Python 2 和 Python 3 上给出了相同的结果)。
map
不是必需的,但根据我的经验,将迭代与纯粹的每元素转换分开会导致代码更清晰、更易读。这是separating concerns 的问题,不是我的 FP 恋物癖 ;)
@sum2000 我已经更新了我的匹配。其他答案也可以使用相同的基本思想。
@agf 我试过了,但只有子列表 1 的前两个 intable 字符串被转换为 int【参考方案3】:
如何使用 map 和 lambda
>>> map(lambda x:int(x) if x.isdigit() else x,['sam','1','dad','21'])
['sam', 1, 'dad', 21]
或使用列表理解
>>> [int(x) if x.isdigit() else x for x in ['sam','1','dad','21']]
['sam', 1, 'dad', 21]
>>>
正如评论中提到的,由于 isdigit 可能无法捕获负数,因此这里有一个处理它的精炼条件,值得注意的是,如果字符串是字母数字而不是字母,则字符串是数字:-)
>>> [int(x) if x.isalnum() and not x.isalpha() else x for x in ['sam','1','dad','21']]
['sam', 1, 'dad', 21]
【讨论】:
str.isdigit()
不是检验int()
是否有效的正确测试,特别是当您可以有负值时。调用int()
是正确的测试。
我在做l1=[int(x) if x.isdigit() else x for x in l]
,它显示错误AttributeError: 'list' object has no attribute 'isdigit'
@sum2000 此方法仅在列表中的所有项目都是字符串时才有效。听起来您列表中的某些项目不是。
l是如何定义的?你能告诉我[type(x) for x in l]
的结果吗?
您的更新版本对于负数仍然是错误的。 '-21'.isalnum()
是 False
。调用int
并处理错误是唯一始终有效的简单解决方案。并非所有内容都需要单线。【参考方案4】:
对于多维列表,使用递归技术可能会有所帮助。
from collections import Iterable
def intify(maybeLst):
try:
return int(maybeLst)
except:
if isinstance(maybeLst, Iterable) and not isinstance(lst, str):
return [intify(i) for i in maybeLst] # here we call intify itself!
else:
return maybeLst
maybeLst = [[['sam', 2],'1'],['dad','21']]
print intify(maybeLst)
【讨论】:
【参考方案5】:使用isdigit()
检查字符串中的每个字符是否为数字。
例子:
mylist = ['foo', '3', 'bar', '9']
t = [ int(item) if item.isdigit() else item for item in mylist ]
print(t)
【讨论】:
查看 Thomas 对其他等效答案的评论,了解为什么这可能是错误的。 不应该"-1"
能够转换成int吗?【参考方案6】:
使用list comprehension 验证每个列表项的数值。
str.isnumeric
不会传递负号
使用str.lstrip
删除-
,检查.isnumeric
,如果是则转换为int
。
或者,使用str.isdigit
代替.isnumeric
。
保留列表中的所有值
l = ['sam', '1', 'dad', '21', '-10']
t = [int(v) if v.lstrip('-').isnumeric() else v for v in l]
print(t)
>>> ['sam', 1, 'dad', 21, -10]
删除非数字值
l = ['sam', '1', 'dad', '21', '-10']
t = [int(v) for v in t if v.lstrip('-').isnumeric()]
print(t)
>>> [1, 21, -10]
嵌套列表
l = [['aa', '2'], ['bb', '3'], ['sam', '1', 'dad', '21', '-10']]
t = [[int(v) if v.lstrip('-').isnumeric() else v for v in x] for x in l]
print(t)
>>> [['aa', 2], ['bb', 3], ['sam', 1, 'dad', 21, -10]]
【讨论】:
以上是关于如何将 intable 字符串列表转换为 int的主要内容,如果未能解决你的问题,请参考以下文章