2012-03-18 46 views
38

说我有一个字符串,这是一个元组应该是,例如,"(1,2,3,4,5)"。将其转换为实际元组最简单的方法是什么?什么我想要做的一个例子是:从字符串解析元组?

tup_string = "(1,2,3,4,5)" 
tup = make_tuple(tup_string) 

只需运行tuple()串上使整个事情一大元组,而我想要做的就是理解字符串作为一个元组。我知道我可以使用一个正则表达式,但我希望有一个更便宜的方法。想法?

+0

哪里串从何而来? – 2012-03-18 23:55:54

回答

79

already exists

>>> from ast import literal_eval as make_tuple 
>>> make_tuple("(1,2,3,4,5)") 
(1, 2, 3, 4, 5) 

注意的角落的情况下,虽然:

>>> make_tuple("(1)") 
1 
>>> make_tuple("(1,)") 
(1,) 

如果输入格式比Python的作品不同,这里,你需要单独处理这种情况,或使用其他方法一样tuple(int(x) for x in tup_string[1:-1].split(','))

+4

令人惊讶的是,有多少关于SO的问题可以用ast.literal_eval,itertools.product和只有少数库函数来回答。 – DSM 2012-03-18 23:07:22

+0

@DSM:如果至少像'groupby'或'groupby'这样有趣的东西,对分:) :) – 2012-03-18 23:08:42

+0

不错的一个!我不知道这一个XD – 2012-03-18 23:08:43

2

您可以分析您的字符串不SyntaxError

def parse_tuple(string): 
    try: 
     s = eval(string) 
     if type(s) == tuple: 
      return s 
     return 
    except: 
     return 

这个函数返回Tuple如果分析是成功的。否则返回None

print parse_tuple("('A', 'B', 'C')") 
0

我们也可以自己解析它。 比方说,我们有元组返回被Python象下面这样:

((2, 'C/C++', 0, 'clang_cpp'), (3, 'Python相关', 0, 'python')) 

我这里还有我们如何做

首先,我们继续阅读的元组字符串中的字符,但存储最后左分号的位置,以及如何许多分号,我们有见面(我们可以把它叫做左分号水平,因此对于右分号),当我们遇到一个合适的分号,我们做以下的事情:

  1. 采取从最后的分号子到当前权分号。 (在 这个潜艇tring,没有更多的分号,我们只用“,”将它分成 数组。假设新阵列为M
  2. 然后我们将M附加到我们的结果数组中,该数组将存储所有M
  3. 第三,删除我们从原始字符串中取得的子字符串。 最后,做同样的事情,像第1步,直到左右 分号的能级进入0

的JavaScript代码如下所示:

function parseTuple(t){ 
 
    var lc = "("; 
 
    var rc = ")"; 
 
    var lc_level = 0; 
 
    var rc_level = 0; 
 
    var last_lc = 0; 
 
    var last_rc = 0; 
 
    var result = []; 
 
    for(i=0;i<t.length;i++){ 
 
     if(t[i] == lc){ 
 
      lc_level++; 
 
      last_lc = i; 
 
     }else if(t[i] == rc){ 
 
      rc_level++; 
 
      last_rc = i; 
 
     } 
 
     if(rc_level == 1){ 
 
      var substr = t.slice(last_lc+1,last_rc); 
 
      var data = substr.split(","); 
 
      result.push(data); 
 
      lc_level--; 
 
      rc_level--; 
 
      i = 0; 
 
      t = t.slice(0,last_lc) + t.substring(last_rc+1); 
 
     } 
 
     if(lc_level == rc_level && lc_level==0){ 
 
      break; 
 
     } 
 
    } 
 
    return result; 
 
}

1

我会推荐使用literal_eval

如果你不舒服literal_eval或想有什么被转换更多的控制你也可以拆开串,并转换值,并重新创建的元组。

听起来比它更复杂的,真的,这是一个班轮:

eg = '(102,117,108)' 
eg_tuple = map(int, eg.replace('(','').replace(')','').split(','))) 

这将抛出一个ValueError如果元组中的任何元素(字符串)是无法转换为int一样,例如字符串中的'1.2''(1.2, 3, 4)'


同样可以用regex实现:

import re 
eg = '(102,117,108)' 
et_tuple = tuple(map(int, re.findall(r'[0-9]+', eg)))