我正在处理来自preflib.org的数据,特别是与#34;与Ties的订单"格式。格式看起来(有点)像这样:
1,2,{3,4,5},6
2,{3,6,4},1,5
{2,3},{4,6},{1,5}
...
我需要将这些文件的每一行解析为元组列表,其中每个元组都包含一个"等价类"选择。在这个例子中:
1,2,{3,4,5},6 -> [(1,), (2,), (3,4,5), (6,)]
2,{3,6,4},1,5 -> [(2,), (3,6,4), (1), (5,)]
{2,3},{4,6},{1,5} -> [(2,3), (4,6), (1,5)]
目前,这是通过丑陋的字符串操作等解决的。我非常确定有更多的pythonic来解决这个问题(最好只使用内置函数)。
编辑:我现在做的事情(非常hacky和丑陋......):s = "1,2,{3,4,5},6"
classes = []
equiv_cls = None
for token in s.split(","):
if token.startswith("{"):
equiv_cls = [token[1:]]
elif token.endswith("}"):
equiv_cls.append(token[:-1])
classes.append(tuple(equiv_cls))
equiv_cls = None
elif equiv_cls is not None:
equiv_cls.append(token)
else:
classes.append(tuple(token))
答案 0 :(得分:4)
您可以ast.literal_eval
使用str.replace
次来电:
>>> from ast import literal_eval
>>> s = '1,2,{3,4,5},6'
>>> [x if isinstance(x, tuple) else (x,) for x
in literal_eval(s.replace('{', '(').replace('}', ')'))]
[(1,), (2,), (3, 4, 5), (6,)]
正如@Martijn Pieters建议您可以通过一次str.replace
来电替换两个str.translate
来电:
>>> from string import maketrans
>>> table = maketrans('{}', '()')
>>> [x if isinstance(x, tuple) else (x,) for x in literal_eval(s.translate(table))]
[(1,), (2,), (3, 4, 5), (6,)]
在Python 3中,您不再需要str.replace
或str.translate
个调用,它在Python 2.7中失败,而这里是related bug:
>>> [tuple(x) if isinstance(x, set) else (x,) for x in literal_eval(s)]
[(1,), (2,), (3, 4, 5), (6,)]
答案 1 :(得分:0)
这是一个非常粗糙和愚蠢的方法,但值得一看
x = "2,{3,6,4},1,5"
y = x.replace("{",'(')
y = y.replace("}",')')
y = '['+y+']'
j = []
y = eval(y)
for i in y:
typ = str(type(i))
if(typ == "<class 'int'>"):
j.append((i,))
else:
j.append(i)
print (j)
答案 2 :(得分:0)
另一种正则表达式方法:
def parse_orders_with_ties(s):
s2 = re.sub(r"{([\d,]+)}|(\d+)", r"(\g<0>,)", s)
s2 = re.sub(r"[{}]", "", s2)
v = ast.literal_eval("[" + s2 + "]")
return v
答案 3 :(得分:0)
为了将此数据转换为所需的列表,必须进行字符串操作。完成基本操作后,只能使用内置函数将数据转换为列表。
以下功能可能是一种解决方案:
def convert(str_data):
b = str_data.split(',')
list_data = []
flag = 0
for each_elem in b:
if flag == 0 :
next_str = ''
if '{' in each_elem :
next_str += each_elem.split('{')[1] + ','
flag = 1
elif flag == 1 and '}' not in each_elem :
next_str += each_elem + ','
elif flag == 1 and '}' in each_elem:
next_str += each_elem.split('}')[0]
list_data.append(next_str)
flag = 0
else:
list_data.append(each_elem)
return list_data
z = convert(“{2,3},{4,6},{1,5}”)
ž
['2,3','4,6','1,5']