3

我有一个这样的字符串:

'(459..521),(1834..2736)'

我想让它看起来像这样:

[(459, 521), (1834, 2736)]

也就是说,具有值的元组列表,而不是字符串。

到目前为止,这是我想出的:

def parseAnnotation(annotation):
thing=[]
number=""
for c in annotation:
    if c.isdigit()==True:
        number=number+c
    else:
        thing.append(number)
        number=""
thing.append(number)
thing = filter(None, thing)
return thing

输出:

['459', '521', '1834', '2736']

我有一种感觉,我走的路比必要的要长,因此非常欢迎对更简单的方法提出意见。请多多包涵,我对 Python 很陌生。谢谢。

4

4 回答 4

2
def parseAnnotation(annotation):
    return [tuple(pair[1:-1].split('..')) for pair in annotation.split(',')]

 

编辑:literal_eval速度较慢(并且更少的pythonic IMO):

In [4]: %timeit list(ast.literal_eval(strs.replace('..',',')))
100000 loops, best of 3: 17.8 us per loop

In [5]: %timeit [tuple(pair[1:-1].split('..')) for pair in strs.split(',')]
1000000 loops, best of 3: 1.22 us per loop

 

另一个编辑:忘记了你需要ints.

def parseAnnotation(annotation):
    return [tuple(map(int, pair[1:-1].split('..'))) for pair in annotation.split(',')]

这有点难以理解,让我们把它写成一个循环:

def parseAnnotation(annotation):
    result = []
    for pair in annotation.split(','):
        a, b = pair[1:-1].split('..')
        result.append( (int(a), int(b)) )
    return result

您决定它是否需要处理无效输入。

于 2012-12-28T13:05:08.060 回答
1
import ast
annotation = '(459..521),(1834..2736)'

def parseAnnotation(annotation):
    return list(ast.literal_eval(annotation.replace('..', ',')))

# returns [(459, 521), (1834, 2736)]
于 2012-12-28T13:04:35.870 回答
0

使用ast.literal_eval()

In [9]: import ast

In [11]: strs='(459..521),(1834..2736)'

In [12]: strs=strs.replace("..",",")

In [13]: lis=ast.literal_eval(strs)

In [14]: lis
Out[14]: ((459, 521), (1834, 2736))

In [16]: list(lis)
Out[16]: [(459, 521), (1834, 2736)]
于 2012-12-28T13:05:03.543 回答
0

好的,我在这里给出一个无 ast 的答案(ast 暂时不在我的简历中)

s = '(459..521),(1834..2736)'
result = []
for x in s.split(','):
    x = x.strip('()')
    x = x.split('..')
    x = [int(i) for i in x]
    result.append(tuple(x))
print result

始终尝试获取字符串中的模式并使用字符串方法进行一些操作。

于 2012-12-28T15:29:51.947 回答