【发布时间】:2019-04-15 15:36:06
【问题描述】:
背景
对于某些背景,我正在尝试创建一个使用 Python 3.5 将工作表转换为 API 调用的工具
为了将表格单元格转换为 API 调用所需的架构,我已经开始使用类似 javascript 的语法来处理电子表格中使用的标题。例如:
工作表标题(字符串)
dict.list[0].id
Python 字典
{
"dict":
"list": [
{"id": "my cell value"}
]
}
标头架构也可能有嵌套的数组/字典:
one.two[0].three[0].four.five[0].six
而且我还需要在创建对象后在遍历每个标头时附加到该对象。
我尝试过的
添加分支
基于https://stackoverflow.com/a/47276490/2903486,我可以使用one.two.three.four 之类的值设置嵌套字典,并且可以在遍历行时附加到现有字典,但我无法添加对数组:
def add_branch(tree, vector, value):
key = vector[0]
tree[key] = value \
if len(vector) == 1 \
else add_branch(tree[key] if key in tree else {},
vector[1:],
value)
return tree
file = Worksheet(filePath, sheet).readRow()
rowList = []
for row in file:
rowObj = {}
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList
我自己的 add_branch 版本
import re, json
def branch(tree, vector, value):
"""
Used to convert JS style notation (e.g dict.another.array[0].id) to a python object
Originally based on https://stackoverflow.com/a/47276490/2903486
"""
# Convert Boolean
if isinstance(value, str):
value = value.strip()
if value.lower() in ['true', 'false']:
value = True if value.lower() == "true" else False
# Convert JSON
try:
value = json.loads(value)
except:
pass
key = vector[0]
arr = re.search('\[([0-9]+)\]', key)
if arr:
arr = arr.group(0)
key = key.replace(arr, '')
arr = arr.replace('[', '').replace(']', '')
newArray = False
if key not in tree:
tree[key] = []
tree[key].append(value \
if len(vector) == 1 \
else branch({} if key in tree else {},
vector[1:],
value))
else:
isInArray = False
for x in tree[key]:
if x.get(vector[1:][0], False):
isInArray = x[vector[1:][0]]
if isInArray:
tree[key].append(value \
if len(vector) == 1 \
else branch({} if key in tree else {},
vector[1:],
value))
else:
tree[key].append(value \
if len(vector) == 1 \
else branch({} if key in tree else {},
vector[1:],
value))
if len(vector) == 1 and len(tree[key]) == 1:
tree[key] = value.split(",")
else:
tree[key] = value \
if len(vector) == 1 \
else branch(tree[key] if key in tree else {},
vector[1:],
value)
return tree
还有什么需要帮助的
在添加了一些东西之后,我的分支解决方案现在实际上运行得很好,但我想知道我是否在这里做错/混乱,或者是否有更好的方法来处理我正在编辑嵌套数组的位置(我的尝试开始了在代码的if IsInArray 部分中)
我希望这两个标题可以编辑最后一个数组,但我最终在第一个数组上创建了一个重复的字典:
file = [{
"one.array[0].dict.arrOne[0]": "1,2,3",
"one.array[0].dict.arrTwo[0]": "4,5,6"
}]
rowList = []
for row in file:
rowObj = {}
for colName, rowValue in row.items():
rowObj.update(add_branch(rowObj, colName.split("."), rowValue))
rowList.append(rowObj)
return rowList
输出:
[
{
"one": {
"array": [
{
"dict": {
"arrOne": [
"1",
"2",
"3"
]
}
},
{
"dict": {
"arrTwo": [
"4",
"5",
"6"
]
}
}
]
}
}
]
代替:
[
{
"one": {
"array": [
{
"dict": {
"arrOne": [
"1",
"2",
"3"
],
"arrTwo": [
"4",
"5",
"6"
]
}
}
]
}
}
]
【问题讨论】:
-
也许我在这里遗漏了一个细节,但是您的字符串如何指示后面任何选择器的列表索引位置?例如在“dict.list[].id”中:如果
list看起来像[{'id': 1}, {'id': 2}],你怎么知道你指的是哪个id? -
@benvc 是的,那是我试图弄清楚自己的一件事(也许通过将其放在标题中,例如
list[0].id或通过检查指标是否是像list.1.id这样的 int - 希望它可能是最后一个,但还没有完全弄清楚 -
编辑:添加了更好版本的 add_branch 方法,(几乎)可以正确处理数组
标签: python arrays python-3.x dictionary