使用Ties文件解析preflib订单的Pythonic方法

时间:2014-11-26 13:37:37

标签: python string parsing

我正在处理来自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))

4 个答案:

答案 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.replacestr.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']