Python list.remove 第二个列表中的项目



我搜索了一下,我看到的大多数错误都是当人们试图迭代列表并同时修改它时。就我而言,我正在尝试获取一个列表,并从该列表中删除第二个列表中存在的项目。

import pymysql
schemaOnly = ["table1", "table2", "table6", "table9"]
db = pymysql.connect(my connection stuff)
tables = db.cursor()
tables.execute("SHOW TABLES")
tablesTuple = tables.fetchall()
tablesList = []
# I do this because there is no way to remove items from a tuple
# which is what I get back from tables.fetchall
for item in tablesTuple:
tablesList.append(item)
for schemaTable in schemaOnly:
tablesList.remove(schemaTable)

当我在代码中放入各种打印语句时,一切看起来都正常,并且会正常工作。但是当它到达实际tablesList.remove(schemaTable)时,我得到了可怕的ValueError: list.remove(x): x not in list.

如果有更好的方法可以做到这一点,我对想法持开放态度。对我来说,遍历列表并删除项目似乎是合乎逻辑的。

提前感谢!

**编辑**

评论中的每个人和第一个答案都是正确的。失败的原因是,从元组到列表的转换正在创建一个格式非常糟糕的列表。因此,在下一个循环中尝试删除项目时,没有任何匹配项。此问题的解决方案是从每个元组中获取第一项,并将它们放入如下所示的列表中:tablesList = [x[0] for x in tablesTuple]。完成此操作后,第二个循环工作并且表名被正确删除。

感谢您为我指出正确的方向!

我假设fetchall返回元组,每个匹配的数据库行一个元组。

现在的问题是tablesList中的元素是元组,而schemaTable包含字符串。Python不认为这些是平等的。

因此,当你尝试用schemaTable的字符串在tablesList上调用remove时,Python找不到任何这样的值。

您需要检查tablesList中的值并找到将它们转换为字符串的方法。我怀疑这是通过简单地从元组中取出第一个元素,但我手头没有 mySQL 数据库,所以我无法测试它。

关于您的问题,如果有更好的方法可以做到这一点:是的。

您可以仅追加所需的项目,而不是将项目添加到列表中,然后删除它们。例如:

for item in tablesTuple:
if item not in schemaOnly:
tablesList.append(item)

此外,schemaOnly 可以写成一个集合,以提高搜索复杂度从 O(n) 到 O(1):

schemaOnly = {"table1", "table2", "table6", "table9"}

这只对大列表有意义,但根据我的经验,它在语义上很有用。

最后,您可以在一个列表理解中编写整个内容:

tablesList = [item for item in tablesTuple if item not in schemaOnly]

如果你不需要保留重复(或者一开始就没有任何重复),你也可以这样做:

tablesSet = set(tablesTuple) - schemaOnly

在所有这些变化中,它也是最好的大O复杂性。

最新更新