python - Python:将通配符匹配应用于从字典中读取的键
问题描述
这是针对我在 Blender 中运行的脚本,但问题与它的 Python 部分有关。它不是特定于 Blender 的。
该脚本最初来自这个答案,它将给定的材料(键)替换为其较新的等效物(值)。
这是代码:
import bpy
objects = bpy.context.selected_objects
mat_dict = {
"SOLID-WHITE": "Sld_WHITE",
"SOLID-BLACK": "Sld_BLACK",
"SOLID-BLUE": "Sld_BLUE"
}
for obj in objects:
for slot in obj.material_slots:
slot.material = bpy.data.materials[mat_dict[slot.material.name]]
问题是,当场景可能不仅有材质为“SOLID-WHITE”的对象,还有“SOLID-WHITE.001”、“SOLID-WHITE.002”等对象时,如何处理重复项。
我正在查看关于 Python 中通配符的问题的答案,它似乎fnmatch
非常适合这项任务。
我试过fnmatch
进入代码的最后一行。我也试过用它包装字典键(我知道很湿)。这些方法都没有奏效。
如何在每个字典键上运行通配符匹配?
因此,例如,一个对象是否具有“SOLID-WHITE”或“SOLID-WHITE”-dot-some-number,它仍然会被替换为“Sld_WHITE”吗?
解决方案
有两种方法可以解决这个问题。您可以制作一个匹配模糊名称的智能词典。或者您可以更改用于查找颜色的键。
这是使用 fnmatch 的第一种方法的示例。当颜色包含数字时,这种方法将查找时间复杂度从 O(1) 更改为 O(n)。这种方法用一种方法扩展了UserDict__missing__
。__missing__
如果在字典中找不到键,则调用该方法。它使用 fnmatch 将每个键与给定键进行比较。
from collections import UserDict
import fnmatch
import bpy
objects = bpy.context.selected_objects
class Colors(UserDict):
def __missing__(self, key):
for color in self.keys():
if fnmatch.fnmatch(key, color + "*"):
return self[color]
raise KeyError(f"could not match {key}")
mat_dict = Colors({
"SOLID-WHITE": "Sld_WHITE",
"SOLID-BLACK": "Sld_BLACK",
"SOLID-BLUE": "Sld_BLUE"
})
for obj in objects:
for slot in obj.material_slots:
slot.material = bpy.data.materials[mat_dict[slot.material.name]]
这是使用正则表达式的第二种方法的示例。
import re
import bpy
objects = bpy.context.selected_objects
mat_dict = {
"SOLID-WHITE": "Sld_WHITE",
"SOLID-BLACK": "Sld_BLACK",
"SOLID-BLUE": "Sld_BLUE"
}
pattern = re.compile(r"([A-Z\-]+)(?:\.\d+)?")
# matches any number of capital letters and dashes
# can be followed by a dot followed by any number of digits
# this pattern can match the following strings
# ["AAAAA", "----", "AA-AA.00005"]
for obj in objects:
for slot in obj.material_slots:
match = pattern.fullmatch(slot.material.name)
if match:
slot.material = bpy.data.materials[mat_dict[match.group(1)]]
else:
slot.material = bpy.data.materials[mat_dict[slot.material.name]]
推荐阅读
- r - 如何对数据框的所有行值执行基于向量的函数
- javascript - 如果悬停并超出边界,如何停止调整 chart.js 的大小?
- python - Visual Studio Python 项目不符合最新语法
- python - 如何使用 Altair 从 transform_regression 标记线?
- sql - 使用该列中的值的总和向列中添加一行
- node.js - 当 axios 请求看到响应状态码在 400 和 500 范围内时,它会去 catch 块
- python - Python将日期时间设置为索引并执行前向填充错误
- java - 使用 Java 在 Thymeleaf 中避免特殊字符转义
- spring - 如何在使用 JPA 获取后返回一对一关系的值?
- java - 我们可以为不同的 ssl 上下文使用相同的 webclient 吗?