我想知道最简单的方法是将如下列表的字符串表示转换为列表:
x = '[ "A","B","C" , " D"]'
即使在用户在逗号之间加空格,在引号内加空格的情况下,我也需要处理它并将其转换为:
x = ["A", "B", "C", "D"]
我知道我可以用strip()和split()分隔空格,并检查非字母字符。但代码变得非常笨拙。有没有我不知道的快速功能?
我想知道最简单的方法是将如下列表的字符串表示转换为列表:
x = '[ "A","B","C" , " D"]'
即使在用户在逗号之间加空格,在引号内加空格的情况下,我也需要处理它并将其转换为:
x = ["A", "B", "C", "D"]
我知道我可以用strip()和split()分隔空格,并检查非字母字符。但代码变得非常笨拙。有没有我不知道的快速功能?
当前回答
因此,根据所有答案,我决定对最常见的方法进行计时:
from time import time
import re
import json
my_str = str(list(range(19)))
print(my_str)
reps = 100000
start = time()
for i in range(0, reps):
re.findall("\w+", my_str)
print("Regex method:\t", (time() - start) / reps)
start = time()
for i in range(0, reps):
json.loads(my_str)
print("JSON method:\t", (time() - start) / reps)
start = time()
for i in range(0, reps):
ast.literal_eval(my_str)
print("AST method:\t\t", (time() - start) / reps)
start = time()
for i in range(0, reps):
[n.strip() for n in my_str]
print("strip method:\t", (time() - start) / reps)
regex method: 6.391477584838867e-07
json method: 2.535374164581299e-06
ast method: 2.4425282478332518e-05
strip method: 4.983267784118653e-06
所以最终正则表达式获胜!
其他回答
使用纯Python-不导入任何库:
[x for x in x.split('[')[1].split(']')[0].split('"')[1:-1] if x not in[',',' , ',', ']]
如果您知道您的列表只包含带引号的字符串,这个pyparsing示例将为您提供剥离字符串的列表(甚至保留原始Unicode特性)。
>>> from pyparsing import *
>>> x =u'[ "A","B","C" , " D"]'
>>> LBR,RBR = map(Suppress,"[]")
>>> qs = quotedString.setParseAction(removeQuotes, lambda t: t[0].strip())
>>> qsList = LBR + delimitedList(qs) + RBR
>>> print qsList.parseString(x).asList()
[u'A', u'B', u'C', u'D']
如果您的列表可以有更多的数据类型,甚至可以在列表中包含列表,那么您将需要一个更完整的语法-如pyparsing-examples目录中的语法,它将处理元组、列表、int、浮点和带引号的字符串。
我想用正则表达式提供一个更直观的模式化解决方案。下面的函数将包含任意字符串的字符串化列表作为输入。
逐步解释:您删除了所有的白间距、括号和value_separator(如果它们不是要提取的值的一部分,否则会使正则表达式更复杂)。然后将清理后的字符串拆分为单引号或双引号,并取非空值(或奇数索引值,无论首选项如何)。
def parse_strlist(sl):
import re
clean = re.sub("[\[\],\s]","",sl)
splitted = re.split("[\'\"]",clean)
values_only = [s for s in splitted if s != '']
return values_only
测试样本:“['21',”foo“'6','0',”A“]”
因此,根据所有答案,我决定对最常见的方法进行计时:
from time import time
import re
import json
my_str = str(list(range(19)))
print(my_str)
reps = 100000
start = time()
for i in range(0, reps):
re.findall("\w+", my_str)
print("Regex method:\t", (time() - start) / reps)
start = time()
for i in range(0, reps):
json.loads(my_str)
print("JSON method:\t", (time() - start) / reps)
start = time()
for i in range(0, reps):
ast.literal_eval(my_str)
print("AST method:\t\t", (time() - start) / reps)
start = time()
for i in range(0, reps):
[n.strip() for n in my_str]
print("strip method:\t", (time() - start) / reps)
regex method: 6.391477584838867e-07
json method: 2.535374164581299e-06
ast method: 2.4425282478332518e-05
strip method: 4.983267784118653e-06
所以最终正则表达式获胜!
如果有字符串化的字典列表,json模块是更好的解决方案。可以使用json.loads(your_data)函数将其转换为列表。
>>> import json
>>> x = '[ "A","B","C" , " D"]'
>>> json.loads(x)
['A', 'B', 'C', ' D']
类似地
>>> x = '[ "A","B","C" , {"D":"E"}]'
>>> json.loads(x)
['A', 'B', 'C', {'D': 'E'}]