python - 如何使用部分字符串匹配搜索字典列表并且不区分大小写,然后显示结果?
问题描述
我正在创建通过导入 csv 文件创建的两个列表的字典。这两个列表中的每一个都包含多个字典列表,每个列表有 8 个键:值对。每个字典都包含有关一个特定项目的信息。其中一个列表是有关多本书的信息;另一个是有关多部电影的信息。
我需要通过允许用户输入查询字符串来查询图书列表,该查询字符串将用于搜索图书列表中的多个字段。搜索需要执行部分字符串匹配并且不区分大小写。应显示所有匹配书籍的所有详细信息,而不重复任何条目。
如果它与查询字符串匹配,如何搜索列表并打印整个字典?
# Note to self: book_collection is a list
# ORDER OF INFO in book_collection: title, author, publisher, pages, year, copies, available, ID
def query_book_collection(book_collection):
# check to see if the string is in the dictionary--partial string matching and case insensitive
query_string = input("Enter a query string to use for the search: ")
if query_string.lower() in book_collection:
print(book_collection)
else:
print("Sorry, that search returned no results.")
以我现在编码的方式,我希望它只匹配完整的直接匹配(不是部分字符串匹配),然后打印完整的 book_collection;但是,它只会打印“抱歉,该搜索未返回任何结果”。
编辑:我已将 query_string.lower 更新为 query_string.lower()。
书籍词典有22个列表,我相信每个列表都是一本字典。一个列表(来自调试器)如下所示,例如:
:{“标题”:“我有史以来最好的书”,“作者”:“约瑟夫考德威尔”,“出版商”:“FPG Publishing”,“页数”:“317”,“年份”:“2014”,“副本” :3,“可用”:3,“ID”:17001}
目标是能够搜索任何短语,如果该短语出现在上面的字典中,则将打印整个字典。
对于那些询问的人,这里有更多代码可以提供更大的上下文。我最初分享的代码就在长打印菜单的下方:
# each subset of the collection.
def load_collections():
# Load the two collections.
book_collection, max_book_id = load_collection("books.csv")
movie_collection, max_movie_id = load_collection("movies.csv")
# Check for error.
if book_collection is None or movie_collection is None:
return None, None
# Return the composite dictionary.
return {"books": book_collection, "movies": movie_collection}, max(max_book_id, max_movie_id)
# Loads a single collection and returns the data as a list. Upon error, None is returned.
def load_collection(file_name):
max_id = -1
try:
# Create an empty collection.
collection = []
# Open the file and read the field names
collection_file = open(file_name, "r")
field_names = collection_file.readline().rstrip().split(",")
# Read the remaining lines, splitting on commas, and creating dictionaries (one for each item)
for item in collection_file:
field_values = item.rstrip().split(",")
collection_item = {}
for index in range(len(field_values)):
if (field_names[index] == "Available") or (field_names[index] == "Copies") or (field_names[index] == "ID"):
collection_item[field_names[index]] = int(field_values[index])
else:
collection_item[field_names[index]] = field_values[index]
# Add the full item to the collection.
collection.append(collection_item)
# Update the max ID value
max_id = max(max_id, collection_item["ID"])
# Close the file now that we are done reading all of the lines.
collection_file.close()
# Catch IO Errors, with the File Not Found error the primary possible problem to detect.
except FileNotFoundError:
print("File not found when attempting to read", file_name)
return None
except IOError:
print("Error in data file when reading", file_name)
return None
# Return the collection.
return collection, max_id
# Display the menu of commands and get user's selection. Returns a string with the user's requested command.
# No validation is performed.
def prompt_user_with_menu():
print("\n\n********** Welcome to the Collection Manager. **********")
print("COMMAND FUNCTION")
print(" ci Check in an item")
print(" co Check out an item")
print(" ab Add a new book")
print(" am Add a new movie")
print(" db Display books")
print(" dm Display movies")
print(" qb Query for books")
print(" qm Query for movies")
print(" x Exit")
return input("Please enter a command to proceed: ")
# Create the query function. Prompts user to enter query string for a book and
# displays ALL results--partial string matching and case insensitive. Note to self: book_collection is a list
# ORDER OF INFO in book_collection: title, author, publisher, pages, year, copies, available, ID
def query_book_collection(book_collection):
# check to see if the string is in the dictionary--partial string matching and case insensitive
query_string = input("Enter a query string to use for the search: ")
if query_string.lower() in book_collection:
print(book_collection)
else:
print("Sorry, that search returned no results.")
def query_movie_collection():
pass
def check_out():
pass
def check_in():
pass
def get_item_ID():
pass
def display_collection():
pass
def add_book():
pass
def add_movie():
pass
# This is the main program function. It runs the main loop which prompts the user and performs the requested actions.
def main():
# Load the collections, and check for an error.
library_collections, max_existing_id = load_collections()
if library_collections is None:
print("The collections could not be loaded. Exiting.")
return
print("The collections have loaded successfully.")
# Display the error and get the operation code entered by the user. We perform this continuously until the
# user enters "x" to exit the program. Calls the appropriate function that corresponds to the requested operation.
operation = prompt_user_with_menu()
while operation != "x":
if operation == "ci":
check_in(library_collections)
elif operation == "co":
check_out(library_collections)
elif operation == "ab":
max_existing_id = add_book(library_collections["books"], max_existing_id)
elif operation == "am":
max_existing_id = add_movie(library_collections["movies"], max_existing_id)
elif operation == "db":
display_collection(library_collections["books"])
elif operation == "dm":
display_collection(library_collections["movies"])
elif operation == "qb":
query_book_collection(library_collections["books"])
elif operation == "qm":
query_movie_collection(library_collections["movies"])
else:
print("Unknown command. Please try again.")
operation = prompt_user_with_menu()
# Start the program.
main()
解决方案
在使用运算符之前,您可以将集合中的所有值连接在一起in
:
def query_book_collection(book_collection):
query_string = input("Enter a query string to use for the search: ")
collection_string = ",".join(map(str, book_collection.values())).lower()
if query_string.lower() in collection_string:
print(book_collection)
else:
print("Sorry, that search returned no results.")
book_collection
但更有效的方法应该是添加一个新属性,当您在load_collection
函数中加载集合时,它将所有要查询的值连接起来。喜欢(使用 python 内置csv
模块读取 csv 文件):
def load_collection(file_name):
try:
with open(file_name, "r") as f:
reader = csv.DictReader(f)
collection = []
max_id = -1
for item in reader:
# add a field for querying
item["_fulltext"] = ",".join(item.values())
# casting type
item["Available"] = int(item["Available"])
item["Copies"] = int(item["Copies"])
item["ID"] = int(item["ID"])
collection.append(item)
max_id = max(max_id, item["ID"])
return collection, max_id
except FileNotFoundError:
print("File not found when attempting to read", file_name)
return None, None
except IOError:
print("Error in data file when reading", file_name)
return None, None
然后,您的查询功能将是:
def query_book_collection(book_collection):
query_string = input("Enter a query string to use for the search: ")
if query_string.lower() in book_collection["_fulltext"]:
print(book_collection)
else:
print("Sorry, that search returned no results.")
推荐阅读
- java - 使用 Elastic Search 高级别的客户端获取类型的映射
- c# - 将字节转换为 PDF 文件
- r - rfe() 函数错误:$ 运算符对原子向量无效
- android - 撰写:从另一个 TextStyle 继承 TextStyle
- java - 如何在 Java 中使用自定义字符集将字节数组编码为 Base 63 字符串?
- docker - 从交互式 docker 容器在主机上运行命令
- html - 当标签的 href 是一个 html 文件并添加了下载属性时,期望是什么?
- powershell - 使用 PowerShell Where-Object 不适用于 Get-ChildItem
- python - 无法将符号张量 ({}) 转换为 numpy 数组。”
- javascript - 如何根据状态值动态显示组件