搜索并从元组列表中删除

时间:2014-04-03 00:47:38

标签: python list tuples

我有一个以元组形式列出的待办事项列表......

  

[(datetime.datetime(2014,2,28,0,0),'教程登录'),(datetime.datetime(2014,4,9,0,0),&#39 ;作业1'),(datetime.datetime(2014,4,22,0,0),'作业2'),(datetime.datetime(2014,6,14,0,0) ,'考试研究'),(datetime.datetime(2014,3,15,0,0),'购买杂货'),(datetime.datetime(2014,3,20, 0,0),'洗衣'),(datetime.datetime(2014,3,26,0,0),'数学作业'),(datetime.datetime(2014,3) ,31,0,0),'写todo list'),(datetime.datetime(2014,4,4,0,0),'申请工作'),( datetime.datetime(2014,4,14,0,0),'拖延'),(datetime.datetime(2014,4,19,0,0),'买复活节彩蛋' ;),(datetime.datetime(2014,4,25,0,0),'购买anzac饼干')]

我试图编写一个函数,如果要执行的任务与名称匹配,将从列表中删除元组,如果没有找到名称,则返回False。这就是我到目前为止所做的,但即使任务存在,我也总是假的。

def remove_item(todolist, name):
for t in todolist:
    if t[1] is name:
        del t
    else:
        return False

3 个答案:

答案 0 :(得分:2)

您的代码的问题在于您正在测试引用相等'is'运算符)而不是值相等'=='运算符)

E.g。

>>> a = 'tutorial signons'
>>> b = 'tutorial signons'

a is b将返回False,但a == b将返回True

有关详细信息,请参阅this

因此,这应该做你期望的事情:

  def remove_item(todo_list, name):
     for t in todolist:
         if t[1] == name:
            del t
         else:
            return False

但是,从正在迭代的列表中删除元素并不是一个好主意。您可能想要创建一个新列表或使用以下内容:

filtered_list = filter(lambda x: x[1] != 'some_string', todo_list)

这将从匹配some_sting的列表中删除每个元组。

答案 1 :(得分:1)

在迭代它时从列表中删除项目是一个坏主意(它会弄乱列表迭代器,因此您在删除每个项目后跳过测试项目)。如果你有两个项目要一个接一个地删除,那么,你刚刚失败了。

有三种方法可以解决这个问题;

  1. 以相反的顺序遍历列表(有点乱,但它有效)

  2. 使用列表推导 - 构建新列表,省略要“删除”的值。这通常是最清楚的阅读。

  3. 遍历列表并保留要删除的索引列表,然后浏览索引列表以删除和删除(项目i - 已删除的项目数),即补偿列表缩减。也很乱。

  4. 选项2看起来像

    def remove_item(todolist, name):
        result = [item for item in todolist if name != item[1]]
        if len(todolist) == len(result):
            return False  # nothing removed
        else:
            return result
    

答案 2 :(得分:0)

您的代码存在一些问题:

  1. 使用比较对象身份is运算符。使用==来获得您的期望。
  2. 在迭代期间删除项目会搞砸迭代器。而是捕获要删除的项的索引,并在循环外删除它。更好的选择是filter列表或使用列表推导来获取新列表。
  3. 您的return False声明是错误的缩进。它应该在for循环之外。
  4. 我会写这样的代码:

    def remove_item(todo_list, item):
        return filter(lambda x: x[1] != item, todo_list)