我想知道最简单的方法是将如下列表的字符串表示转换为列表:
x = '[ "A","B","C" , " D"]'
即使在用户在逗号之间加空格,在引号内加空格的情况下,我也需要处理它并将其转换为:
x = ["A", "B", "C", "D"]
我知道我可以用strip()和split()分隔空格,并检查非字母字符。但代码变得非常笨拙。有没有我不知道的快速功能?
我想知道最简单的方法是将如下列表的字符串表示转换为列表:
x = '[ "A","B","C" , " D"]'
即使在用户在逗号之间加空格,在引号内加空格的情况下,我也需要处理它并将其转换为:
x = ["A", "B", "C", "D"]
我知道我可以用strip()和split()分隔空格,并检查非字母字符。但代码变得非常笨拙。有没有我不知道的快速功能?
当前回答
如果有字符串化的字典列表,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'}]
其他回答
这是你能做到的,
**
x = '[ "A","B","C" , " D"]'
print(list(eval(x)))
**最好的答案是公认的答案
虽然这不是一个安全的方法,但最好的答案是公认的。当答案发布时,我并没有意识到评估的危险。
import ast
l = ast.literal_eval('[ "A","B","C" , " D"]')
l = [i.strip() for i in l]
假设您的所有输入都是列表,并且输入中的双引号实际上无关紧要,这可以通过简单的正则表达式替换来完成。这有点过时,但它就像一种魅力。还要注意,输出现在是一个Unicode字符串列表,您没有指定需要它,但考虑到Unicode输入,它似乎是有意义的。
import re
x = u'[ "A","B","C" , " D"]'
junkers = re.compile('[[" \]]')
result = junkers.sub('', x).split(',')
print result
---> [u'A', u'B', u'C', u'D']
junkers变量包含我们不需要的所有字符的编译正则表达式(为了速度),使用]作为字符需要一些反斜杠技巧。re.sub将所有这些字符都替换为空,我们在逗号处拆分得到的字符串。
注意,这也会从条目u'[“oh no”]'->[u'ohno']中删除空格。如果这不是您想要的,则需要对regexp进行一些升级。
不需要导入任何内容或进行评估。对于大多数基本用例,包括原始问题中给出的用例,您可以在一行中完成此操作。
一个衬垫
l_x = [i.strip() for i in x[1:-1].replace('"',"").split(',')]
解释
x = '[ "A","B","C" , " D"]'
# String indexing to eliminate the brackets.
# Replace, as split will otherwise retain the quotes in the returned list
# Split to convert to a list
l_x = x[1:-1].replace('"',"").split(',')
输出:
for i in range(0, len(l_x)):
print(l_x[i])
# vvvv output vvvvv
'''
A
B
C
D
'''
print(type(l_x)) # out: class 'list'
print(len(l_x)) # out: 4
您可以根据需要使用列表理解来解析和清理此列表。
l_x = [i.strip() for i in l_x] # list comprehension to clean up
for i in range(0, len(l_x)):
print(l_x[i])
# vvvvv output vvvvv
'''
A
B
C
D
'''
嵌套列表
如果您有嵌套列表,它确实会变得有点烦人。如果不使用正则表达式(这将简化替换),并且假设您希望返回一个扁平列表(python的zen表示扁平优于嵌套):
x = '[ "A","B","C" , " D", ["E","F","G"]]'
l_x = x[1:-1].split(',')
l_x = [i
.replace(']', '')
.replace('[', '')
.replace('"', '')
.strip() for i in l_x
]
# returns ['A', 'B', 'C', 'D', 'E', 'F', 'G']
如果您需要保留嵌套列表,它会变得有点难看,但仍然可以通过正则表达式和列表理解来完成:
import re
x = '[ "A","B","C" , " D", "["E","F","G"]","Z", "Y", "["H","I","J"]", "K", "L"]'
# Clean it up so the regular expression is simpler
x = x.replace('"', '').replace(' ', '')
# Look ahead for the bracketed text that signifies nested list
l_x = re.split(r',(?=\[[A-Za-z0-9\',]+\])|(?<=\]),', x[1:-1])
print(l_x)
# Flatten and split the non nested list items
l_x0 = [item for items in l_x for item in items.split(',') if not '[' in items]
# Convert the nested lists to lists
l_x1 = [
i[1:-1].split(',') for i in l_x if '[' in i
]
# Add the two lists
l_x = l_x0 + l_x1
最后一个解决方案可以处理任何以字符串形式存储的列表,无论是否嵌套。
从上面使用基本Python包的一些答案中,我比较了几个(使用Python 3.7.3)的性能:
方法1:ast
import ast
list(map(str.strip, ast.literal_eval(u'[ "A","B","C" , " D"]')))
# ['A', 'B', 'C', 'D']
import timeit
timeit.timeit(stmt="list(map(str.strip, ast.literal_eval(u'[ \"A\",\"B\",\"C\" , \" D\"]')))", setup='import ast', number=100000)
# 1.292875313000195
方法2:json
import json
list(map(str.strip, json.loads(u'[ "A","B","C" , " D"]')))
# ['A', 'B', 'C', 'D']
import timeit
timeit.timeit(stmt="list(map(str.strip, json.loads(u'[ \"A\",\"B\",\"C\" , \" D\"]')))", setup='import json', number=100000)
# 0.27833264000014424
方法3:不导入
list(map(str.strip, u'[ "A","B","C" , " D"]'.strip('][').replace('"', '').split(',')))
# ['A', 'B', 'C', 'D']
import timeit
timeit.timeit(stmt="list(map(str.strip, u'[ \"A\",\"B\",\"C\" , \" D\"]'.strip('][').replace('\"', '').split(',')))", number=100000)
# 0.12935059100027502
我很失望地看到,我认为可读性最差的方法是性能最好的方法。。。在选择最具可读性的选项时,需要考虑一些权衡。。。对于我使用Python的工作负载类型,我通常看重可读性,而不是性能稍高的选项,但这通常取决于。