繁体   English   中英

将一串元组拆分为元组

[英]Splitting a string of tuples into tuples

我有一串元组,每个元组用逗号分隔。 如何将其拆分为元组列表?

例如,我想分割这个字符串:

"(2,3) (3, 4) ( 5, 4)"

进入这个元组数组:

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

请注意元组中可能有空格(如"(3, 4)" ),因此str.split()然后使用eval()将不起作用。

您可以将re.splitast.literal_eval re.split使用:

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

如果这些总是像你声称的两位数的元组,只需使用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)]

另一种方式可能是:

  • 首先,您可以用逗号分割并获取所有数字的列表。
  • 然后,使用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)]

您可以使用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)]

如果您不想使用任何库或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)]

这可以通过删除所有空格并取出第一个和最后一个括号,分割依据)(并将剩余的字符串转换为带有整数的元组

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM