在 Python 中处理从 MySQL 数据库中提取的数据
Handling data pulled from MySQL database in Python
我正在尝试找出一种通过 MySQL 数据库处理单词黑名单的好方法。在处理从数据库返回的数据时,我遇到了障碍。
cursor.execute('SELECT word FROM blacklist')
blacklist1 = []
for word in cursor.fetchall():
if word in blacklist1:
return
else:
blacklist1.append(word)
上面的代码是我用来提取我知道有效的信息的代码。但是,我需要一些帮助来转换它:
[('word1',), ('word2',), ('word3',), ('word4',), ('word5',)]
进入这个:
['word1', 'word2', 'word3', 'word4', 'word5']
我最大的问题是我需要它进行扩展,以便在必要时检查黑名单中的每个单词,从没有到数千个。我知道在检查它们与它检查的消息时,for 循环会起作用。但我知道在它是一个正常列表之前我将无法检查单词。任何帮助将不胜感激。
您的列表当前包含一个元素元组。如果你想提取字符串,你可以试试这个:
blacklist1 = []
for word_tuple in cursor.fetchall():
if word_tuple[0] in blacklist1:
return
else:
blacklist1.append(word_tuple[0])
对于您的用例,您可能还受益于将 blacklist1
设为集合,这样您就可以在 O(1) 时间内检查成员资格:
blacklist1 = set()
for word_tuple in cursor.fetchall():
if word_tuple[0] in blacklist1:
return
else:
blacklist1.add(word_tuple[0])
在 for word in cursor.fetchall()
的每次迭代中,变量 word
是一个 元组 或值的集合。这已记录在案 here。
这些对应于返回的每一列,即如果您在 select 语句中有第二列('SELECT word, replacement FROM blacklist')
您将得到两个元素的元组。
使用集合,并添加元组的唯一元素,而不是元组本身:
for word_tuple in cursor.fetchall():
blacklist1.add(word[0])
仔细查看代码,if word in blacklist1: return
可能是一个逻辑错误 - 一旦您看到重复项,您就会停止从数据库中读取行。您可能只想跳过 that duplicate - 您实际上不再需要该逻辑,因为 sets 会自动删除重复项。
首先,您的实际问题是游标是对从 MySQL 返回的行进行迭代的包装器,因此它可以像元组列表一样进行操作。话虽如此,我的建议是将您的“业务”逻辑与数据访问逻辑分开。这可能看起来微不足道,但它会使调试更容易。总体方法如下所示:
def get_from_database():
cursor.execute('SELECT word FROM blacklist')
return [row[0] for row in cursor.fetchall()]
def get_blacklist():
words = get_from_database()
return list(set(words))
在这种方法中,get_from_database
以程序需要的格式从 MySQL 和 returns 中检索所有单词。 get_blacklist
封装了这个逻辑,也使得返回的列表唯一。所以现在,如果有错误,您可以独立验证每个。
我正在尝试找出一种通过 MySQL 数据库处理单词黑名单的好方法。在处理从数据库返回的数据时,我遇到了障碍。
cursor.execute('SELECT word FROM blacklist')
blacklist1 = []
for word in cursor.fetchall():
if word in blacklist1:
return
else:
blacklist1.append(word)
上面的代码是我用来提取我知道有效的信息的代码。但是,我需要一些帮助来转换它:
[('word1',), ('word2',), ('word3',), ('word4',), ('word5',)]
进入这个:
['word1', 'word2', 'word3', 'word4', 'word5']
我最大的问题是我需要它进行扩展,以便在必要时检查黑名单中的每个单词,从没有到数千个。我知道在检查它们与它检查的消息时,for 循环会起作用。但我知道在它是一个正常列表之前我将无法检查单词。任何帮助将不胜感激。
您的列表当前包含一个元素元组。如果你想提取字符串,你可以试试这个:
blacklist1 = []
for word_tuple in cursor.fetchall():
if word_tuple[0] in blacklist1:
return
else:
blacklist1.append(word_tuple[0])
对于您的用例,您可能还受益于将 blacklist1
设为集合,这样您就可以在 O(1) 时间内检查成员资格:
blacklist1 = set()
for word_tuple in cursor.fetchall():
if word_tuple[0] in blacklist1:
return
else:
blacklist1.add(word_tuple[0])
在 for word in cursor.fetchall()
的每次迭代中,变量 word
是一个 元组 或值的集合。这已记录在案 here。
这些对应于返回的每一列,即如果您在 select 语句中有第二列('SELECT word, replacement FROM blacklist')
您将得到两个元素的元组。
使用集合,并添加元组的唯一元素,而不是元组本身:
for word_tuple in cursor.fetchall():
blacklist1.add(word[0])
仔细查看代码,if word in blacklist1: return
可能是一个逻辑错误 - 一旦您看到重复项,您就会停止从数据库中读取行。您可能只想跳过 that duplicate - 您实际上不再需要该逻辑,因为 sets 会自动删除重复项。
首先,您的实际问题是游标是对从 MySQL 返回的行进行迭代的包装器,因此它可以像元组列表一样进行操作。话虽如此,我的建议是将您的“业务”逻辑与数据访问逻辑分开。这可能看起来微不足道,但它会使调试更容易。总体方法如下所示:
def get_from_database():
cursor.execute('SELECT word FROM blacklist')
return [row[0] for row in cursor.fetchall()]
def get_blacklist():
words = get_from_database()
return list(set(words))
在这种方法中,get_from_database
以程序需要的格式从 MySQL 和 returns 中检索所有单词。 get_blacklist
封装了这个逻辑,也使得返回的列表唯一。所以现在,如果有错误,您可以独立验证每个。