Изменение списка за пределами области видимости - PullRequest
0 голосов
/ 25 декабря 2018

Я пытаюсь удалить элемент из списка, например так:

TodoList=[{'ID':5,'TodoItem':'walk','isDone':False}];

def RemoveItem(ID):
     if not any(todoItem['ID'] == ID for todoItem in TodoList):
          return 'item does not exist';

     RemovedList=list(filter(lambda todoItem:todoItem['ID']!= ID,TodoList))
     TodoList=RemovedList

не работает, я тоже пробовал это:

 def RemoveItem(ID):
         nonlocal TodoList
         if not any(todoItem['ID'] == ID for todoItem in TodoList):
              return 'item does not exist';

         TodoList=list(filter(lambda todoItem:todoItem['ID']!= ID,TodoList))

кто-нибудь знает, чтопроблема?

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Возможное решение - найти индекс предмета с идентификатором и использовать pop :

todo_list = [{'ID': 5, 'TodoItem': 'walk', 'isDone': False}]


def remove_item(ID):
    if not any(todoItem['ID'] == ID for todoItem in todo_list):
        return 'item does not exist'

    # get index of id
    idx = next(i for i, e in enumerate(todo_list) if e['ID'] == ID)

    # remove and return
    return todo_list.pop(idx)


print(remove_item(4))
print(remove_item(5))
print(todo_list)

Выход

item does not exist
{'isDone': False, 'ID': 5, 'TodoItem': 'walk'}
[]

Проблема с вашей первой попыткой состоит в том, что когда вы делаете: TodoList=RemovedList внутри функции, она создает новую локальную переменную внутри функции, даже если есть глобальная переменная с тем же именем.Во второй попытке вам нужно установить глобальный вместо нелокального:

todo_list = [{'ID': 5, 'TodoItem': 'walk', 'isDone': False}]

def RemoveItem(ID):
    global todo_list
    if not any(todoItem['ID'] == ID for todoItem in todo_list):
        return 'item does not exist';

    todo_list = list(filter(lambda todoItem: todoItem['ID'] != ID, todo_list))


RemoveItem(5)
print(todo_list)

Выход

[]

Далее

  1. Документация по global
0 голосов
/ 25 декабря 2018

Одно возможное исправление.

Передача списка задач (list of dict) в качестве параметра, поэтому он мутирует:

TodoList=[{'ID':5,'TodoItem':'walk','isDone':False}, {'ID':6,'TodoItem':'talk','isDone':True}]

def RemoveItem(ID, TodoList):
     if not any(todoItem['ID'] == ID for todoItem in TodoList):
          print('item does not exist');
     else:
      for item in TodoList:
        if item['ID']== ID: TodoList.remove(item)


RemoveItem(5, TodoList)

print(TodoList)
#=> [{'ID': 6, 'TodoItem': 'talk', 'isDone': True}]


Чтобы ваше решение работало, вам нужно вернуть:
def RemoveItem(ID, TodoList):
     if not any(todoItem['ID'] == ID for todoItem in TodoList):
          return 'item does not exist';
     else:
      return list(filter(lambda todoItem:todoItem['ID']!= ID, TodoList))


print(RemoveItem(5, TodoList))
#=> [{'ID': 6, 'TodoItem': 'talk', 'isDone': True}]

Это потому, что строка list(filter(lambda todoItem:todoItem['ID']!= ID, TodoList)) не изменяет список, она извлекает элементы на основе условия.

Но лучше вернуть сам список, если естьнет элемента для удаления, вместо возврата строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...