字符串数组坐标转换为 python 中的整数数组
Array of strings coordinates into array of integers in python
我有一个字符串数组的方式坐标:
A = [ '(0.0),(3,3),(5,8)', '(1,2),(5,8),(8,9),(20,6)' , '(45,6),(91,5),(86,4)' , '(100,2),(105,8),(53,6)']
我需要将它们转换成整数,到目前为止我已经尝试使用 int(A
) 或 float(A)
.
来转换它
通过使用 int()
我得到这个错误:
"ValueError: invalid literal for int() with base 10: '(0, 0),(3, 0),(6, 0),(6, 5),(13, 0),(25, 5),(27, 5),(29, 5),(30, 0),(35, 5),(37, 5),(38, 5),(45, 0),(52, 0),(53, 5),(56, 0),(58, 0),(60, 0),(60, 5),(61, 5),(66, 0),(66, 5),(73, 0),(74, 0),(75, 5),(76"
(假设 0.0 是错字)
根据 S3DEV 的建议,一种快速的方法是使用某种类型的 eval()
,但不推荐这样做。
[list(eval(i)) for i in A]
[[(0, 0), (3, 3), (5, 8)],
[(1, 2), (5, 8), (8, 9), (20, 6)],
[(45, 6), (91, 5), (86, 4)],
[(100, 2), (105, 8), (53, 6)]]
eval
与 literal_eval
的比较
eval:
这非常强大,但如果您接受来自不受信任的输入的字符串进行评估,这也非常危险。想象一下在 rm -rf /
!!
上使用 eval
ast.literal_eval:
仅对一组有限的 python 文字结构进行操作。这使得 if 更安全。
在你的情况下,因为你的输入是坐标字符串(确保这一点!),那么这两种方法对你来说都是一样的safe/unsafe。
正如我在对该问题的评论中提到的,一种方法是使用安全的 eval
方法,例如 ast.literal_eval
将字符串解析为元组。
假设 (0.0)
应该是 (0,0)
:
import ast
[ast.literal_eval(i) for i in A]
输出:
[((0, 0), (3, 3), (5, 8)),
((1, 2), (5, 8), (8, 9), (20, 6)),
((45, 6), (91, 5), (86, 4)),
((100, 2), (105, 8), (53, 6))]
正则表达式解决方案怎么样?恕我直言,更干净一点,不需要使用 eval
.
import re
A = ['(0,0),(3,3),(5,8)', '(1,2),(5,8),(8,9),(20,6)', '(45,6),(91,5),(86,4)', '(100,2),(105,8),(53,6)']
pattern = re.compile(r'\((\d+), *(\d+)\)')
[[(int(x), int(y)) for x, y in position] for position in [re.findall(pattern, group) for group in A]]
>> [[(0, 0), (3, 3), (5, 8)],
[(1, 2), (5, 8), (8, 9), (20, 6)],
[(45, 6), (91, 5), (86, 4)],
[(100, 2), (105, 8), (53, 6)]]
我有一个字符串数组的方式坐标:
A = [ '(0.0),(3,3),(5,8)', '(1,2),(5,8),(8,9),(20,6)' , '(45,6),(91,5),(86,4)' , '(100,2),(105,8),(53,6)']
我需要将它们转换成整数,到目前为止我已经尝试使用 int(A
) 或 float(A)
.
通过使用 int()
我得到这个错误:
"ValueError: invalid literal for int() with base 10: '(0, 0),(3, 0),(6, 0),(6, 5),(13, 0),(25, 5),(27, 5),(29, 5),(30, 0),(35, 5),(37, 5),(38, 5),(45, 0),(52, 0),(53, 5),(56, 0),(58, 0),(60, 0),(60, 5),(61, 5),(66, 0),(66, 5),(73, 0),(74, 0),(75, 5),(76"
(假设 0.0 是错字)
根据 S3DEV 的建议,一种快速的方法是使用某种类型的 eval()
,但不推荐这样做。
[list(eval(i)) for i in A]
[[(0, 0), (3, 3), (5, 8)],
[(1, 2), (5, 8), (8, 9), (20, 6)],
[(45, 6), (91, 5), (86, 4)],
[(100, 2), (105, 8), (53, 6)]]
eval
与 literal_eval
上使用 evaleval:
这非常强大,但如果您接受来自不受信任的输入的字符串进行评估,这也非常危险。想象一下在rm -rf /
!!ast.literal_eval:
仅对一组有限的 python 文字结构进行操作。这使得 if 更安全。
在你的情况下,因为你的输入是坐标字符串(确保这一点!),那么这两种方法对你来说都是一样的safe/unsafe。
正如我在对该问题的评论中提到的,一种方法是使用安全的 eval
方法,例如 ast.literal_eval
将字符串解析为元组。
假设 (0.0)
应该是 (0,0)
:
import ast
[ast.literal_eval(i) for i in A]
输出:
[((0, 0), (3, 3), (5, 8)),
((1, 2), (5, 8), (8, 9), (20, 6)),
((45, 6), (91, 5), (86, 4)),
((100, 2), (105, 8), (53, 6))]
正则表达式解决方案怎么样?恕我直言,更干净一点,不需要使用 eval
.
import re
A = ['(0,0),(3,3),(5,8)', '(1,2),(5,8),(8,9),(20,6)', '(45,6),(91,5),(86,4)', '(100,2),(105,8),(53,6)']
pattern = re.compile(r'\((\d+), *(\d+)\)')
[[(int(x), int(y)) for x, y in position] for position in [re.findall(pattern, group) for group in A]]
>> [[(0, 0), (3, 3), (5, 8)],
[(1, 2), (5, 8), (8, 9), (20, 6)],
[(45, 6), (91, 5), (86, 4)],
[(100, 2), (105, 8), (53, 6)]]