我想知道最简单的方法是将string如下列表转换为list:
x = u'[ "A","B","C" , " D"]'
Run Code Online (Sandbox Code Playgroud)
即使用户在逗号和引号内的空格之间放置空格也是如此.我需要处理它:
x = ["A", "B", "C", "D"]
Run Code Online (Sandbox Code Playgroud)
在Python中.
我知道我可以剥夺的空间与strip()和split()使用拆分操作和检查非字母.但是代码变得非常糟糕.有一个我不知道的快速功能吗?
小智 667
>>> import ast
>>> x = u'[ "A","B","C" , " D"]'
>>> x = ast.literal_eval(x)
>>> x
['A', 'B', 'C', ' D']
>>> x = [n.strip() for n in x]
>>> x
['A', 'B', 'C', 'D']
Run Code Online (Sandbox Code Playgroud)
使用ast.literal_eval,您可以安全地评估表达式节点或包含Python表达式的字符串.提供的字符串或节点可能只包含以下Python文字结构:字符串,数字,元组,列表,dicts,布尔值和None.
Mar*_*ers 74
这eval很危险 - 你不应该执行用户输入.
如果你有2.6或更新,使用ast而不是eval:
>>> import ast
>>> ast.literal_eval('["A","B" ,"C" ," D"]')
["A", "B", "C", " D"]
Run Code Online (Sandbox Code Playgroud)
一旦你有了,那strip就是字符串.
如果您使用的是旧版本的Python,则可以使用简单的正则表达式非常接近您想要的内容:
>>> x='[ "A", " B", "C","D "]'
>>> re.findall(r'"\s*([^"]*?)\s*"', x)
['A', 'B', 'C', 'D']
Run Code Online (Sandbox Code Playgroud)
这不如ast解决方案,例如它不能正确处理字符串中的转义引号.但它很简单,不涉及危险的评估,并且如果你使用的是较旧的Python,可能对你的目的来说已经足够好了.
Rya*_*yan 66
json只要存在字典化的字典列表,该模块就是更好的解决方案.该json.loads(your_data)函数可用于将其转换为列表.
>>> import json
>>> x = u'[ "A","B","C" , " D"]'
>>> json.loads(x)
[u'A', u'B', u'C', u' D']
Run Code Online (Sandbox Code Playgroud)
同样
>>> x = u'[ "A","B","C" , {"D":"E"}]'
>>> json.loads(x)
[u'A', u'B', u'C', {u'D': u'E'}]
Run Code Online (Sandbox Code Playgroud)
小智 14
受上述一些与基本 python 包一起使用的答案的启发,我比较了一些(使用 Python 3.7.3)的性能:
方法一: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
Run Code Online (Sandbox Code Playgroud)
方法二: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
Run Code Online (Sandbox Code Playgroud)
方法三:不导入
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
Run Code Online (Sandbox Code Playgroud)
我很失望地看到我认为可读性最差的方法是性能最好的方法......在使用最易读的选项时需要考虑权衡......对于我通常使用python的工作负载类型比性能稍高的选项更重视可读性,但像往常一样,这取决于。
tos*_*osh 12
import ast
l = ast.literal_eval('[ "A","B","C" , " D"]')
l = [i.strip() for i in l]
Run Code Online (Sandbox Code Playgroud)
bor*_*ked 12
无需导入任何内容或进行评估。对于大多数基本用例,您可以在一行中完成此操作,包括原始问题中给出的用例。
l_x = [i.strip() for i in x[1:-1].replace('"',"").split(',')]
Run Code Online (Sandbox Code Playgroud)
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(',')
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
您可以根据需要使用列表理解来解析和清理此列表。
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
'''
Run Code Online (Sandbox Code Playgroud)
如果你有嵌套列表,它确实会变得有点烦人。不使用正则表达式(这会简化替换),并假设你想返回一个扁平列表(Python 的禅宗说扁平比嵌套更好):
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']
Run Code Online (Sandbox Code Playgroud)
如果您需要保留嵌套列表,它会变得有点难看,但仍然可以仅使用正则表达式和列表理解来完成:
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
Run Code Online (Sandbox Code Playgroud)
最后一个解决方案适用于任何存储为字符串的列表,无论是否嵌套。
小智 10
你可以这样做
**
x = '[ "A","B","C" , " D"]'
print(eval(x))
Run Code Online (Sandbox Code Playgroud)
** 最好的答案是已接受的答案
尽管这不是一种安全的方法,但最好的答案是公认的答案。发布答案时没有意识到评估危险。
有一个快速的解决方案:
x = eval('[ "A","B","C" , " D"]')
Run Code Online (Sandbox Code Playgroud)
可以通过以下方式删除列表元素中不需要的空格:
x = [x.strip() for x in eval('[ "A","B","C" , " D"]')]
Run Code Online (Sandbox Code Playgroud)
不导入任何内容:
>>> x = u'[ "A","B","C" , " D"]'
>>> ls = x.strip('[]').replace('"', '').replace(' ', '').split(',')
>>> ls
['A', 'B', 'C', 'D']
Run Code Online (Sandbox Code Playgroud)
假设您的所有输入都是列表,并且输入中的双引号实际上无关紧要,可以使用简单的regexp替换来完成.它有点像perl-y但是就像一个魅力.另请注意,输出现在是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']
Run Code Online (Sandbox Code Playgroud)
junkers变量包含我们不想要的所有字符的编译正则表达式(用于速度),使用]作为字符需要一些反斜杠技巧.re.sub将所有这些字符替换为空,我们将结果字符串拆分为逗号.
请注意,这也会从内部条目u'["oh no"]'---> [u'ohno']中删除空格.如果这不是你想要的,那么regexp需要加强一点.
如果您知道您的列表仅包含带引号的字符串,则此 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']
Run Code Online (Sandbox Code Playgroud)
如果您的列表可以有更多的数据类型,甚至列表中包含列表,那么您将需要一个更完整的语法 - 就像pyparsing 示例目录中的语法一样,它将处理元组、列表、整数、浮点数和带引号的字符串。
| 归档时间: |
|
| 查看次数: |
284591 次 |
| 最近记录: |