如何将列表的字符串表示转换为列表

883

我在思考如何将以下字符串表示的列表转换为list的最简单方法:

x = '[ "A","B","C" , " D"]'

即使在用户在逗号之间放置空格,并且在引号内部也放置空格的情况下,我也需要处理并将其转换为:
x = ["A", "B", "C", "D"] 

我知道可以使用strip()split()去除空格并检查非字母字符。但是代码变得非常混乱。是否有我不知道的快速函数?

21个回答

5

如果你确定你的列表只包含引号括起来的字符串,那么这个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示例目录中的这个,它将处理元组、列表、整数、浮点数和带引号的字符串。

3
你在处理作为Pandas DataFrame存储的抓取数据时,可能会遇到这样的问题。
如果值列表以文本形式呈现,则此解决方案非常有效。
def textToList(hashtags):
    return hashtags.strip('[]').replace('\'', '').replace(' ', '').split(',')

hashtags = "[ 'A','B','C' , ' D']"
hashtags = textToList(hashtags)

Output: ['A', 'B', 'C', 'D']

无需外部库。


2
为了进一步完善Ryan的答案,使用JSON,一个非常方便的函数来转换Unicode在这个答案中。例子中包含单引号或双引号。请看这里这里
>print byteify(json.loads(u'[ "A","B","C" , " D"]')
>print byteify(json.loads(u"[ 'A','B','C' , ' D']".replace('\'','"')))
['A', 'B', 'C', ' D']
['A', 'B', 'C', ' D']

这里唯一的新信息是进一步的处理步骤,与所提出的问题无关,并且在大多数情况下介于不相关和有害之间。数据通常应被理解为字符串(在2.x中为unicode对象),而不是字节序列。 - Karl Knechtel

2

当你把以字符串形式存储的列表加载到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现在是列表


1
不确定这与问题有什么关系... list(reader) 返回一个列表,其中每个内部列表都是 csv 列的字符串列表。一开始就没有任何列表的字符串表示... - Tomerikoo
@Tomerikoo,列表的字符串表示与文件中完全相同。 - Hrvoje
不是一个字符串列表的表示形式,而是由字符串组成的列表。当您使用csv.reader读取CSV文件时,每一行都是['1','2','3'],这是一个字符串列表,而不是一个字符串列表的表示形式... - Tomerikoo
@Tomerikoo 你可以将列表存储在文件中,然后使用任何方法来恢复它。 - Hrvoje
1
好的,假设csv文件里面实际上是[1, 2, 3]。假设一个csv行是[1,2,3] 4 5。使用list(reader)读取它将会得到[["[1,2,3]", "4", "5"], ...],然后执行rows[0]将会得到["[1,2,3]", "4", "5"]。再次强调,我不明白这如何回答问题... - Tomerikoo
显示剩余2条评论

1

json.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"]'


0

根据所有答案,我决定计时最常见的方法:

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

所以最终正则表达式胜出!


0

而且可以使用纯Python代码 - 不需要导入任何库:

[x for x in  x.split('[')[1].split(']')[0].split('"')[1:-1] if x not in[',',' , ',', ']]

0

你可以通过从列表的字符串表示中切掉第一个和最后一个字符(参见下面的第三行)来避免使用 .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'>

0

我想用正则表达式提供更直观的模式匹配解决方案。 下面的函数以字符串化列表作为输入,其中包含任意字符串。

逐步解释: 您删除所有空格、括号和值分隔符(前提是它们不是要提取的值的一部分,否则使正则表达式更复杂)。然后,您将清理后的字符串拆分为单引号或双引号,并获取非空值(或奇数索引值,根据个人喜好)。

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']"


0

如果您不想导入任何库,这是另一种解决方案:

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']

这不是你想要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接