提问人:user2514157 提问时间:10/22/2023 更新时间:10/26/2023 访问量:36
sortedcontainers。SortedKeyList:返回具有匹配值的元素
sortedcontainers.SortedKeyList: Return Element with Matching Value of Key
问:
我用来存储字典列表。字典在列表中按(嵌套)键的值(即“token_str”)排序。sortedcontainers
SortedKeyList
它似乎已正确存储在(例如,如下所示)中,该已通过调试器进行了验证。SortedKeyList
self.tokenized_files
但是,当我尝试从列表中检索具有给定键值(即 token_str)的元素(即字典)时,我得到 .TypeError: string indices must be integers, not 'str'
如何使用嵌套键的值从 SortedKeyList 中检索元素(即字典)?优选地,使用有效的搜索算法,例如平分,而不是遍历整个列表。
self.sorted_index_by_token_str = None
self.tokenized_files = SortedKeyList([
{'full_path': '/path/to/file/mdb_00033k__filename1.pdf', 'tokenized_filename': {'basic_filename': 'filename1.pdf', 'token': {'token_str': 'mdb_00033k'}}},
{'full_path': '/path/to/file/mdb_0027zz__filename2.pdf', 'tokenized_filename': {'basic_filename': 'filename2.pdf', 'token': {'token_str': 'mdb_0027zz'}}},
])
def generate_index(self) -> SortedKeyList:
"""Creates an index comprising a list of dicts of tokenized files sorted by token_str.
"""
self.sorted_index_by_token_str = SortedKeyList(
self.tokenized_files,
key=lambda x: x["tokenized_filename"]["token"]["token_str"],
)
# Evaluate: x["tokenized_filename"]["token"]["token_str"]
# Returns: 'mdb_0027zz'
return self.sorted_index_by_token_str
def find_tokenized_file(self) -> dict:
"""Finds a tokenized file in the index by performing a binary search on token_str.
"""
test = self.sorted_index_by_token_str.index("mdb_0027zz")
# ERROR:
# test = self.sorted_index_by_token_str.index("mdb_0027zz")
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# key = self._key(value)
# ^^^^^^^^^^^^^^^^
# key=lambda x: x["tokenized_filename"]["token"]["token_str"],
# ~^^^^^^^^^^^^^^^^^^^^^^
# TypeError: string indices must be integers, not 'str'```
答:
0赞
user2514157
10/23/2023
#1
键必须是整个嵌套字典(而不仅仅是我认为的简单键值)。然后,该方法用于确定元素的索引,并随后进行检查以确认位于索引处的元素是否与键值匹配。bisect_left
self.sorted_index_by_token_str = SortedKeyList(
key=lambda x: x["tokenized_filename"]["token"]["token_str"]
)
key = {"tokenized_filename": {"token": {"token_str": token_str}}}
index = self.sorted_index_by_token_str.bisect_left(key)
# Check if the token_str is found at the returned index
if (
index < len(self.sorted_index_by_token_str)
and self.sorted_index_by_token_str[index]["tokenized_filename"]["token"][
"token_str"
]
== token_str
):
return self.sorted_index_by_token_str[index]
# token_str not found
return None
或者,使用 bisect_key_left(每@user2357112):
from bisect import bisect_key_left
key = {"tokenized_filename": {"token": {"token_str": token_str}}}
index = bisect_key_left(self.sorted_index_by_token_str, key, key=lambda x: x["tokenized_filename"]["token"]["token_str"])
# Check if the token_str is found at the returned index
if (
index < len(self.sorted_index_by_token_str)
and self.sorted_index_by_token_str[index]["tokenized_filename"]["token"][
"token_str"
]
== token_str
):
return self.sorted_index_by_token_str[index]
# token_str not found
return None
评论
0赞
user2514157
10/24/2023
@user2357112我一直在努力完全理解 sortedcontainers 文档,并感谢您的建议。 似乎更明显地适合这种情况,但我在实践中没有看到显着差异。我是否误解了它的使用方式?bisect_key_left
1赞
user2357112
10/24/2023
我说的是方法,你会像.没有.(当你在做这件事时,你不需要调用已经是字典的东西,也不需要在已经是字符串时用它来获取字符串。SortedKeyList
index = self.sorted_index_by_token_str.bisect_key_left(token_str)
bisect.bisect_key_left
dict
f"{token_str}"
token_str
评论