我有一个字符串:
A = "{user_id:34dd833,category:secondary,items:camera,type:sg_ser}"
我需要将它转换为python字典,以便:
A = {"user_id":"34dd833", "category": "secondary", "items": "camera", "type": "sg_ser"}
除此之外,还有两个问题:
1:“items”键应该有多个值,例如:
A = {"user_id":34dd833, "category": "secondary", "items": "camera,vcr,dvd", "type": "sg_ser"}
这显然是以字符串的形式出现的:
A = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"
因此,基于逗号分离推广任何内容都变得毫无用处。
2:字符串的顺序也可以是随机的。所以,字符串也可以这样:
A = "{category:secondary,type:sg_ser,user_id:34dd833,items:camera,vcr,dvd}"
这使得任何按顺序假设为虚假的过程。
在这种情况下该怎么办?非常感谢。
答案 0 :(得分:7)
如果我们可以假设您的输入没有进行任何引用或转义(您的示例没有,但这并不一定意味着它是一个很好的假设),并且您永远不会有逗号分隔的多个键,只有多个值(可能 是一个很好的假设,因为否则格式不明确......):
首先,让我们放下大括号,然后拆分冒号:
>>> A = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"
>>> A[1:-1].split(':')
['user_id', '34dd833,category', 'secondary,items', 'camera,vcr,dvd,type', 'sg_ser']
因此,第一个条目是第一个键,最后一个条目是最后一个值,其间的每个条目是第N个值,后跟逗号,后跟第N + 1个键。那里可能有其他逗号,但最后一个总是从第N + 1个键中分割出第N个值。 (这甚至适用于N = 0 - 没有逗号,所以最后一个逗号不会从第0个键中分割出来。但不幸的是,它不适用于最后一个条目。我稍后会讨论它。)< / p>
我们有很多方法可以做到这一点,但让我们先将代码写成代码,这样你才能理解它的工作原理。
>>> d = {}
>>> entries = A[1:-1].split(':')
>>> for i in range(len(entries)-1):
... key = entries[i].rpartition(',')[-1]
... value = entries[i+1].rpartition(',')[0]
... d[key] = value
这几乎是对的:
>>> d
{'category': 'secondary', 'items': 'camera,vcr,dvd', 'type': '', 'user_id': '34dd833'}
如上所述,它不适用于最后一个。应该明白为什么;如果没有,请查看rpartition(',')
返回的最后一个值。你可以手动修补它,或者只是通过在末尾打包一个额外的,
来作弊(entries = (A[1:-1] + ',').split(':')
)。但是如果你考虑一下,如果你只是rsplit
而不是rpartition
,那么[0]
会做正确的事情。所以让我们这样做。
那么,我们怎样才能清理它呢?
首先让我们将entries
转换为相邻对的列表。现在,每对(n, nplus1)
,n.rpartition(',')[-1]
都是关键,nplus1.rsplit(',', 1)[0]
是对应的值。所以:
>>> A = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"
>>> entries = A[1:-1].split(':')
>>> adjpairs = zip(entries, entries[1:])
>>> d = {k.rpartition(',')[-1]: v.rsplit(',', 1)[0] for k, v in adjpairs}
答案 1 :(得分:2)
这是另一种方式(不是特别健壮,但在样本数据上显示它可能):
import re
text = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"
print dict(re.findall(r'(\w+):(.*?)(?=(?:,\w+:)|$)', text.strip('{}')))
# {'category': 'secondary', 'items': 'camera,vcr,dvd', 'user_id': '34dd833', 'type': 'sg_ser'}