我正在使用
sortedcontainers
SortedKeyList
来存储字典列表。字典在列表中按(嵌套)键的值(即“token_str”)进行排序。
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'```
键需要是整个嵌套字典(而不仅仅是我认为的简单键值)。然后使用
bisect_left
方法来确定元素的索引,并随后检查以确认位于索引处的元素是否与键值匹配。
key = dict({"tokenized_filename": {"token": {"token_str": f"{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