解析 yaml 列表并将其保存到 python 中的变量
Parse yaml list and save it to variables in python
我有 yaml 文件,我想对其进行迭代并将列表中的所有内容保存为同名的新变量。
- app1:
name: example1
host: example1
run: myscript1.sh
tags:
- "user"
- "age"
- "gender"
- app2:
name: example2
host: example4
tags:
- "user"
- "age"
- "height"
代码:
for i in range(0, len(data)):
for key, value in data[i].items():
print(value.get('tags'))
for n in tags:
print(n)
输出:
['user', 'age', 'gender']
user
age
user
['user', 'age', 'height']
user
age
height
希望在新的迭代中将这些值保存为变量,
user = 'user'
age = 'age'
height = 'height'
并在下一次迭代中:
user = 'user'
age = 'age'
gender = 'gender'
所以我可以将这些变量传递给代码中的其他一些东西。
编辑
yaml 变量(例如主机)将填充来自 Elasticsearch 的值。如果我们在标签“age”中定义,我将在 Elasticsearch 中搜索“age”并从文档中获取值,因此它变为“age”:“20”。之后,这个“age”标签将在 sh 脚本中被调用,类似于:
for doc1 in resp['hits']['hits']:
command = f"{value.get('run')} --age {age} #and other tags"
p = subprocess.Popen(command.split(), shell=False, stdout=subprocess.PIPE)
我不太确定你想要什么,但我认为你正在寻找这样的东西:
# test.yml
- app1:
name: example1
host: example1
tags:
- "user"
- "age"
- "gender"
- app2:
name: example2
host: example4
tags:
- "user"
- "age"
- "height"
import yaml
from pathlib import Path
with Path("test.yml").open() as f:
data = yaml.load(f)
out = []
for entry in data:
app, *_ = entry.keys()
tags = {k: k for k in entry[app]["tags"]}
out.append(tags)
print(out)
您可以轻松地通过应用程序名称保存这些内容,方法是制作一个字典。
请注意,我不知道 为什么 你是在冗余 key/value 对之后,如果 tags
实际上应该包含数据(不像你的例子)你将不得不做这样的事情:
tags = {k:v for k, v in entry[app]["tags"].items()}
最后,您当然可以使用 yaml.dump(out)
.
转储回 yaml
** 开箱
我突然想到你可能想解压这个字典到一个函数中。您可以这样做:
def my_fn(user=None, age=None, gender=None, height=None):
print("user", user, "age", age, "gender", gender, "height", height)
out = [{'user': 'user', 'age': 'age', 'gender': 'gender'},
{'user': 'user', 'age': 'age', 'height': 'height'}]
for row in out:
my_fn(**row)
因此 ** 将 dict 解压缩为关键字参数,可能 就是您要查找的内容。 (无论如何,这对我来说比生成具有编程名称的变量更有意义)。注意 app, *_
解压了 entry.keys()
这样我们就可以得到第一个项目而不必将其转换为可索引类型。 dict.keys()
不是生成器,因此您不能使用 next(dict.keys())
。这个特殊的解包是对 python.
的最新(并且非常有用)的补充
编辑:使用这些变量
yaml variable (e.g. host) will be populated with the values from Elasticsearch. If we define in tags "age", I'll search Elasticsearch for "age" and grab value from document, so it becomes "age": "20".
没错。因此,您想查看 条目在 tags
中,然后用正确的值填充它们。所以你想做这样的事情:
for entry in data:
tags = {}
app, *_ = entry.keys()
for tag in in entry[app]["tags"]:
val = get_tag_value_from_elasticsearch(tag)
tags[tag] = val
After that, this "age" tag will be called in sh script
所以---为简单起见,仍然在同一个循环中,但您始终可以将 tags
附加到列表,然后稍后迭代该列表:
cmd = ["command"]
for param, val in tags.items():
cmd += [f"--{param}", str(val)]
res = subprocess.run(cmd, capture_output=True)
print(res.stdout)
注意这里的一些事情:当我可以使用 []
访问时,我避免使用 .get()
在字典中查找值;我使用 subprocess.run
而不是 Popen(如果你想要后台,你必须返回到 Popen),并且我直接在列表中构建命令,而不是构建一个字符串并将其拆分.
此时你想用它做的任何其他事情我认为是另一个问题,所以我将把这个答案留在这里。
我有 yaml 文件,我想对其进行迭代并将列表中的所有内容保存为同名的新变量。
- app1:
name: example1
host: example1
run: myscript1.sh
tags:
- "user"
- "age"
- "gender"
- app2:
name: example2
host: example4
tags:
- "user"
- "age"
- "height"
代码:
for i in range(0, len(data)):
for key, value in data[i].items():
print(value.get('tags'))
for n in tags:
print(n)
输出:
['user', 'age', 'gender']
user
age
user
['user', 'age', 'height']
user
age
height
希望在新的迭代中将这些值保存为变量,
user = 'user'
age = 'age'
height = 'height'
并在下一次迭代中:
user = 'user'
age = 'age'
gender = 'gender'
所以我可以将这些变量传递给代码中的其他一些东西。
编辑
yaml 变量(例如主机)将填充来自 Elasticsearch 的值。如果我们在标签“age”中定义,我将在 Elasticsearch 中搜索“age”并从文档中获取值,因此它变为“age”:“20”。之后,这个“age”标签将在 sh 脚本中被调用,类似于:
for doc1 in resp['hits']['hits']:
command = f"{value.get('run')} --age {age} #and other tags"
p = subprocess.Popen(command.split(), shell=False, stdout=subprocess.PIPE)
我不太确定你想要什么,但我认为你正在寻找这样的东西:
# test.yml
- app1:
name: example1
host: example1
tags:
- "user"
- "age"
- "gender"
- app2:
name: example2
host: example4
tags:
- "user"
- "age"
- "height"
import yaml
from pathlib import Path
with Path("test.yml").open() as f:
data = yaml.load(f)
out = []
for entry in data:
app, *_ = entry.keys()
tags = {k: k for k in entry[app]["tags"]}
out.append(tags)
print(out)
您可以轻松地通过应用程序名称保存这些内容,方法是制作一个字典。
请注意,我不知道 为什么 你是在冗余 key/value 对之后,如果 tags
实际上应该包含数据(不像你的例子)你将不得不做这样的事情:
tags = {k:v for k, v in entry[app]["tags"].items()}
最后,您当然可以使用 yaml.dump(out)
.
** 开箱
我突然想到你可能想解压这个字典到一个函数中。您可以这样做:
def my_fn(user=None, age=None, gender=None, height=None):
print("user", user, "age", age, "gender", gender, "height", height)
out = [{'user': 'user', 'age': 'age', 'gender': 'gender'},
{'user': 'user', 'age': 'age', 'height': 'height'}]
for row in out:
my_fn(**row)
因此 ** 将 dict 解压缩为关键字参数,可能 就是您要查找的内容。 (无论如何,这对我来说比生成具有编程名称的变量更有意义)。注意 app, *_
解压了 entry.keys()
这样我们就可以得到第一个项目而不必将其转换为可索引类型。 dict.keys()
不是生成器,因此您不能使用 next(dict.keys())
。这个特殊的解包是对 python.
编辑:使用这些变量
yaml variable (e.g. host) will be populated with the values from Elasticsearch. If we define in tags "age", I'll search Elasticsearch for "age" and grab value from document, so it becomes "age": "20".
没错。因此,您想查看 条目在 tags
中,然后用正确的值填充它们。所以你想做这样的事情:
for entry in data:
tags = {}
app, *_ = entry.keys()
for tag in in entry[app]["tags"]:
val = get_tag_value_from_elasticsearch(tag)
tags[tag] = val
After that, this "age" tag will be called in sh script
所以---为简单起见,仍然在同一个循环中,但您始终可以将 tags
附加到列表,然后稍后迭代该列表:
cmd = ["command"]
for param, val in tags.items():
cmd += [f"--{param}", str(val)]
res = subprocess.run(cmd, capture_output=True)
print(res.stdout)
注意这里的一些事情:当我可以使用 []
访问时,我避免使用 .get()
在字典中查找值;我使用 subprocess.run
而不是 Popen(如果你想要后台,你必须返回到 Popen),并且我直接在列表中构建命令,而不是构建一个字符串并将其拆分.
此时你想用它做的任何其他事情我认为是另一个问题,所以我将把这个答案留在这里。