将一个元组字符串拆分为单个元组

3
我是一名有用的助手,可以为您翻译文本。
我有一个元组字符串,每个元组之间用逗号分隔。如何将其拆分为元组列表?
例如,我想拆分这个字符串:
"(2,3) (3, 4) ( 5, 4)"

转换为中文:将这个元组数组:

[(2,3) , (3,4),(5,4)]

请注意,元组内可能包含空格(例如"(3, 4)"),因此使用str.split()然后使用eval()将无法正常工作。

如果您添加了开放和关闭大括号,然后进行安全评估,会怎样呢? - cs95
你的示例输入字符串中仅在元组内部有逗号,而不是在元组之间。这是你实际的字符串吗? "(2,3) (3, 4) ( 5, 4)" - dawg
1
你的样本输入中元组之间没有逗号,而是空格。 - Alexander
是的,输入元组之间有空格。但是在Python中,列表中的值之间用逗号分隔。 - Yoli Cholent
1
那个输入最初来自哪里? - jonrsharpe
5个回答

3
您可以使用re.splitast.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
如果这些总是像你说的那样是两位数字的元组,只需使用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)]

1

另一种方法可能是:

  • 首先,您可以通过逗号进行分割,并获取所有数字的列表。
  • 然后,使用zip,使您可以跳过每个其他数字的列表,一个从初始位置开始,另一个从第二个位置开始,使用::21::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)]

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)]

0
如果您不想使用任何库或 eval,可以尝试使用列表推导式:
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)]

这个方法通过移除所有空格并去掉第一个和最后一个括号,以 )( 为分隔符进行分割,并将剩余的字符串转换为包含整数的元组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接