将列表的字符串转换为列表

时间:2019-01-28 10:43:27

标签: python

我想找到一种最快的方法,将内部具有不同类型的列表字符串更改为列表。

例如:

string = '[[Date1,Date2,Number1,Number2],[28Dec2018,29Dec2018,1.24,5]]'

进入

list = [['Date1', 'Date2', 'Number1', 'Number2'], ['28Dec2018', '29Dec2018', 1.24, 5]]

我知道模块ast提供的功能可能会有所帮助,但仅在以下情况下可用:

string = '[["Date1","Date2","Number1","Number2"],["28Dec2018","29Dec2018",1.24,5]]'

谢谢

3 个答案:

答案 0 :(得分:2)

string = '[[Date1,Date2,Number1,Number2],[28Dec2018,29Dec2018,1.24,5]]'
print(string.strip("[]").split(","))

输出:

['Date1', 'Date2', 'Number1', 'Number2'], ['28Dec2018', '29Dec2018', '1.24', '5']

编辑:

string = '[[Date1,Date2,Number1,Number2],[28Dec2018,29Dec2018,1.24,5]]'


st = string.strip("[]").replace("[", "").replace("]", "").split(",")
listA = []
listB = []

c = 0
for s in st:
    c = c + 1
    if c <= 4:
        if s.isdigit():
          listA.append(int(s))
        elif re.match("^\d+?\.\d+?$", s):
            listA.append(float(s))
        else:
            listA.append(s)
    else:
        if s.isdigit():
            listB.append(int(s))
        elif re.match("^\d+?\.\d+?$", s):
            listB.append(float(s))
        else:
            listB.append(s)

print([listA, listB])

输出:

[['Date1', 'Date2', 'Number1', 'Number2'], ['28Dec2018', '29Dec2018', 1.24, 5]]

OR

如果您不想转换intfloat,则它会更短:

for s in st:
    c = c + 1
    if c <= 4:
        listA.append(s)
    else:
        listB.append(s)    
print([listA, listB])

输出:

[['Date1', 'Date2', 'Number1', 'Number2'], ['28Dec2018', '29Dec2018', '1.24', '5']]

OR

如@Bhathiya Perera在评论中所建议,一个使用yaml的班轮杀手:

import yaml
print(yaml.safe_load(string))

答案 1 :(得分:1)

您可以使用正则表达式检测似乎不是数字的所有内容。然后,re.sub用引号将所有这些非数字括起来,即'r'“ \ 1”'

>>> string = '[[Date1,Date2,Number1,Number2],[28Dec2018,29Dec2018,1.24,5]]'    
>>> re.findall(r"(?<=[,\[])(\w*[a-zA-Z]\w*)(?=[,\]])", string)
['Date1', 'Date2', 'Number1', 'Number2', '28Dec2018', '29Dec2018']
>>> re.sub(r"(?<=[,\[])(\w*[a-zA-Z]\w*)(?=[,\]])", r'"\1"', string)
'[["Date1","Date2","Number1","Number2"],["28Dec2018","29Dec2018",1.24,5]]'

这有点丑陋,所以让我们细分一下:

  • (?<=[,\[]):在,[之前
  • (\w*[a-zA-Z]\w*):字母或数字,实际上是字母,以及更多字母或数字
  • (?=[,\]]):后跟,]

现在,您的字符串是有效的JSON 1),并且可以使用json模块进行解析:

>>> import json
>>> json.loads(_)
[['Date1', 'Date2', 'Number1', 'Number2'], ['28Dec2018', '29Dec2018', 1.24, 5]]

这适用于您的问题中给出的示例。对于其他字符串,正则表达式的“字母或数字”部分必须进行大量修改。或者,您可以将所有内容用引号引起来...

>>> re.sub(r"([^,\[\]]+)", r'"\1"', string)
"[['Date1','Date2','Number1','Number2'],['28Dec2018','29Dec2018','1.24','5']]"
>>> lst = json.loads(_)

...,然后在后处理步骤中尽可能递归地转换为intfloat

def try_to_cast(lst):
    for i, x in enumerate(lst):
        if isinstance(x, list):
            try_to_cast(x)
        else:
            try:
                lst[i] = float(x)
                lst[i] = int(x)
            except ValueError:
                pass

>>> try_to_cast(lst)
>>> print(lst)
[['Date1', 'Date2', 'Number1', 'Number2'], ['28Dec2018', '29Dec2018', 1.24, 5]]

1)正如in comments所指出的,您的字符串已经是 有效的YAML,因此可以直接使用yaml模块进行解析预处理或后处理。

答案 2 :(得分:0)

这是一个使用splitstrip和列表理解的班轮;

string = '[[Date1,Date2,Number1,Number2],[28Dec2018,29Dec2018,1.24,5]]'
splitter = [x.split(',') for x in string.strip('[]').split('],[')]
print(splitter)

>>>[['Date1', 'Date2', 'Number1', 'Number2'], ['28Dec2018', '29Dec2018', '1.24', '5']]

尽管如上所述,它没有捕获浮点数/整数,但它们以字符串形式返回。