我有一串元组,其中每个元组都用逗号分隔。如何将其拆分为元组列表?
例如,我想分割此字符串:
"(2,3) (3, 4) ( 5, 4)"
进入此元组数组:
[(2,3) , (3,4),(5,4)]
请注意,元组中可能有空格(例如"(3, 4)"
),因此str.split()
然后使用eval()
无效。
答案 0 :(得分:3)
您可以将re.split
与ast.literal_eval
一起使用:
import re, ast
result = [ast.literal_eval(i) for i in re.split('(?<=\))\s(?=\()', "(2,3) (3, 4) ( 5, 4)")]
输出:
[(2, 3), (3, 4), (5, 4)]
请注意,ast.literal_eval
比内置eval
更安全,因为ast.literal_eval
不会盲目评估传递给它的内容,而是检查输入是否为有效的Python数据类型
但是,如果字符串形式的元组没有用空格隔开,即"(2,3)(3, 4)(5, 6)"
,则上述方法将无效。在这种情况下,您可以创建一个小型解析器:
class Parse:
def __init__(self, _input, _start=''):
self.data, self.group, self.content = _input, _start, []
self.parse()
def __iter__(self):
yield from map(ast.literal_eval, self.content)
def parse(self):
_val = next(self.data, None)
if _val is not None:
if _val == '(':
r = Parse(self.data, _start="(")
self.content.extend(r.content)
self.data = r.data
elif _val == ')':
self.content.append(self.group+')')
else:
self.group += _val
self.parse()
final_result = list(Parse(iter("(2,3)(3, 4)(5, 6)")))
输出:
[(2, 3), (3, 4), (5, 6)]
答案 1 :(得分:1)
如果这些数字始终像您声明的那样是两位数的元组,则只需使用re.findall
:
>>> out = re.findall(r'(\d+),\s*(\d+)', s)
>>> out
[('2', '3'), ('3', '4'), ('5', '4')]
如果需要这些作为整数:
>>> [tuple(map(int, i)) for i in out]
[(2, 3), (3, 4), (5, 4)]
答案 2 :(得分:1)
另一种方式可能是:
zip
,以便使用::2
和1::2
通过从起始位置开始的第二个位置跳过其他数字来分隔数字列表。my_str = "(2,3) (3, 4) ( 5, 4)"
# getting list of digits only
all_numbers = [int(ch) for i in my_str.split(',') for ch in i if ch.isdigit()]
# using zip to convert into tuples
result = list(zip(all_numbers[::2], all_numbers[1::2]))
print(result)
输出为:
[(2, 3), (3, 4), (5, 4)]
答案 3 :(得分:0)
您可以使用re.sub
用,
替换元组之间的空格,然后在literal_eval
中添加括号和提要以解释为Python数据结构:
>>> s="(2,3) (3, 4) ( 5, 4)"
>>> from ast import literal_eval
>>> import re
>>> literal_eval("["+re.sub(r'(?<=\))[ \t]*(?=\()',',',s)+"]")
[(2, 3), (3, 4), (5, 4)]
甚至在元组之间没有空格的情况下也可以使用:
>>> s="(2,3)(3, 4)( 5, 4)"
>>> literal_eval("["+re.sub(r'(?<=\))[ \t]*(?=\()',',',s)+"]")
[(2, 3), (3, 4), (5, 4)]
答案 4 :(得分:0)
如果您不想使用任何库或评估程序,则可以尝试使用列表理解:
public class RetryTest {
@Test
public void execute() throws AggregateException {
Integer result = Retry.execute(getCallableCalculater(), Duration.ofSeconds(1), 3);
assertEquals(9, java.util.Optional.ofNullable(result));
}
private Callable<Integer> getCallableCalculater() {
final Integer[] counter = {0};
return () -> {
for (int i = 0; i < 3; ++i) {
counter[0]++;
System.out.println(MessageFormat.format(
"Counter = {0}", Integer.toString(counter[0])));
}
if (counter[0] < 6)
throw new Exception();
return counter[0];
};
}
}
输出:
a="(2,3) (3, 4) ( 5, 4)"
[tuple(map(int,e.split(','))) for e in a.replace(' ','')[1:-1].split(')(')]
通过删除所有空格并取出第一个和最后一个括号,除以[(2, 3), (3, 4), (5, 4)]
,然后将剩余的字符串转换为带有int的元组,可以实现此目的