我在思考如何将以下字符串表示的列表转换为list
的最简单方法:
x = '[ "A","B","C" , " D"]'
即使在用户在逗号之间放置空格,并且在引号内部也放置空格的情况下,我也需要处理并将其转换为:
x = ["A", "B", "C", "D"]
我知道可以使用strip()
和split()
去除空格并检查非字母字符。但是代码变得非常混乱。是否有我不知道的快速函数?
我在思考如何将以下字符串表示的列表转换为list
的最简单方法:
x = '[ "A","B","C" , " D"]'
x = ["A", "B", "C", "D"]
我知道可以使用strip()
和split()
去除空格并检查非字母字符。但是代码变得非常混乱。是否有我不知道的快速函数?
如果你确定你的列表只包含引号括起来的字符串,那么这个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']
def textToList(hashtags):
return hashtags.strip('[]').replace('\'', '').replace(' ', '').split(',')
hashtags = "[ 'A','B','C' , ' D']"
hashtags = textToList(hashtags)
Output: ['A', 'B', 'C', 'D']
无需外部库。
当你把以字符串形式存储的列表加载到CSV中时,通常会出现这种情况。
如果你将列表以OP所询问的形式存储在CSV中:
x = '[ "A","B","C" , " D"]'
import csv
with open('YourCSVFile.csv') as csv_file:
reader = csv.reader(csv_file, delimiter=',')
rows = list(reader)
listItems = rows[0]
listItems
现在是列表
list(reader)
返回一个列表,其中每个内部列表都是 csv 列的字符串列表。一开始就没有任何列表的字符串表示... - Tomerikoocsv.reader
读取CSV文件时,每一行都是['1','2','3']
,这是一个字符串列表,而不是一个字符串列表的表示形式... - Tomerikoo[1, 2, 3]
。假设一个csv行是[1,2,3] 4 5
。使用list(reader)
读取它将会得到[["[1,2,3]", "4", "5"], ...]
,然后执行rows[0]
将会得到["[1,2,3]", "4", "5"]
。再次强调,我不明白这如何回答问题... - Tomerikoojson.loads()
和 json.dumps()
是 json 包中与 javascript 中的 JSON.parse()
和 JSON.stringify()
等效的方式,因此使用 json 解决方案可以使生活更简单。
import json
a = '[ "A","B","C" , " D"]'
print(json.loads(a)) #['A', 'B', 'C', ' D']
b = ['A', 'B', 'C', ' D']
print(json.dumps(b)) # '["A", "B", "C", " D"]'
根据所有答案,我决定计时最常见的方法:
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[',',' , ',', ']]
你可以通过从列表的字符串表示中切掉第一个和最后一个字符(参见下面的第三行)来避免使用 .strip() 函数:
>>> mylist=[1,2,3,4,5,'baloney','alfalfa']
>>> strlist=str(mylist)
['1', ' 2', ' 3', ' 4', ' 5', " 'baloney'", " 'alfalfa'"]
>>> mylistfromstring=(strlist[1:-1].split(', '))
>>> mylistfromstring[3]
'4'
>>> for entry in mylistfromstring:
... print(entry)
... type(entry)
...
1
<class 'str'>
2
<class 'str'>
3
<class 'str'>
4
<class 'str'>
5
<class 'str'>
'baloney'
<class 'str'>
'alfalfa'
<class 'str'>
我想用正则表达式提供更直观的模式匹配解决方案。 下面的函数以字符串化列表作为输入,其中包含任意字符串。
逐步解释: 您删除所有空格、括号和值分隔符(前提是它们不是要提取的值的一部分,否则使正则表达式更复杂)。然后,您将清理后的字符串拆分为单引号或双引号,并获取非空值(或奇数索引值,根据个人喜好)。
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']"
如果您不想导入任何库,这是另一种解决方案:
x = '[ "A","B","C" , " D"]'
def toList(stringList):
stringList = stringList.split('[')[1]# removes "["
stringList = stringList.split(']')[0]# removes "]"
stringList = stringList.split(',')#gets objects in the list
return [text.strip()[1:-1] for text in stringList] #eliminate additional " or ' in the string.
toList(x)
输出:
['A', 'B', 'C', ' D']
这种方法的注意事项是,如果您的字符串中有逗号,例如如果您的输入为
x = '[ "A","B,F","C" , " D"]'
你的输出将会是
['A', '', '', 'C', ' D']
这不是你想要的。
unicode
对象),而不是字节序列。 - Karl Knechtel