В чем разница между del a_list [:] и a_list = [] в функции? - PullRequest
0 голосов
/ 08 февраля 2019

Это всего лишь вопрос о разнице в коде.

У меня есть несколько списков, т.е.a=[], b=[], c=[], d=[]

Скажем, если у меня есть код, который добавляется к каждому списку, и я хочу сбросить все эти списки в исходное пустое состояние, я создал функцию:

def reset_list():
  del a[:]
  del b[:]
  del c[:]
  del d[:]

Итаквсякий раз, когда я вызываю reset_list() в коде, он удаляет все добавленные элементы и устанавливает все списки на [].Однако приведенный ниже не работает:

def reset_list():
  a = []
  b = []
  c = [] 
  d = []

Возможно, это глупый вопрос, но мне было интересно, почему второй не сработает.

Ответы [ 4 ]

0 голосов
/ 08 февраля 2019

Первый метод работает потому, что:

  • reset_list() просто удаляет содержимое четырех списков.Он работает со списками, которые вы определяете вне функции, при условии, что они названы одинаково.Если у вас другое имя, вы получите сообщение об ошибке:

    e = [1,2,3,4]
    def reset_list():
        del a[:]   #different name for list
    
    NameError: name 'e' is not defined
    

    Функция будет иметь эффект только в том случае, если вы инициализируете списки перед вызовом функции.Это потому, что вы не возвращаете списки после завершения вызова функции:

    a = [1,2,3,4] #initialize before function definition
    def reset_list():
        del a[:]
    
    reset_list() #function call to modify a
    print(a)
    #[]
    

    Сама по себе функция ничего не возвращает:

    print(reset_list())
    #None
    

2-й метод не работает, потому что:

  • функция reset_list() создает 4 пустых списка, которые не указывают на списки, которые могли быть определены вне функции.Что бы ни происходило внутри функции, она остается внутри (также называемой scope ) и заканчивается там, пока вы не return вернете списки в конце вызова функции.Списки будут изменены и возвращены только при вызове функции.Убедитесь, что вы указали аргументы в reset_list(a,..) в определении функции:

    #function definition
    def reset_list(a):
        a = []
        return a
    
    #initialize list after function call
    a = [1,2,3,4]
    print("Before function call:{}".format(a))
    new_a = reset_list(a)
    print("After function call:{}".format(new_a))
    #Output:
    Before function call:[1, 2, 3, 4]
    After function call:[]
    

Как вы видели, вы всегда должны return из функции, чтобы убедиться, чтоВаша функция «выполняет некоторую работу» со списками и в конце возвращает результат.

0 голосов
/ 08 февраля 2019

Вам нужно объявить a, b, c, d как глобальные, если вы хотите, чтобы python использовал глобально определенные «версии» ваших переменных.В противном случае, как указано в других ответах, он просто объявит новые «версии» локальной области видимости.

a = [1,2,3]
b = [1,2,3]
c = [1,2,3]
d = [1,2,3]

def reset_list():
    global a,b,c,d
    a = []
    b = []
    c = [] 
    d = []

print(a,b,c,d)
reset_list()
print(a,b,c,d)

Выходы:

[1, 2, 3] [1, 2, 3] [1, 2, 3] [1, 2, 3]
[] [] [] []

Как указано @ juanpa.arrivillaga , есть разница между del a[:] и a = [].См. этот ответ.

0 голосов
/ 08 февраля 2019

Когда вы делаете del a[:], тогда он ищет переменную a (включая внешние контексты), а затем выполняет del found_a[:].

Но когда вы используете a = [], он создает имя a в текущем контексте и присваивает ему пустой список.Когда функция выходит из переменной a из функции, она больше не «доступна» (уничтожена).

Короче говоря, первое работает, потому что вы изменяете a из внешнего контекста, второе неработать, потому что вы не изменяете a из внешнего контекста, вы просто создаете новое имя a и временно (на время действия функции) присваивает ему пустой список.

Естьразница между del a[:] и a = []

Обратите внимание, что на самом деле они делают что-то другое, что становится очевидным, если у вас есть дополнительные ссылки (псевдонимы) на исходный список.(как отметил @ juanpa.arrivillaga в комментариях)

del list[:] удаляет все элементы в списке, но не создает новый список, поэтому псевдонимы также обновляются:

>>> list_1 = [1,2,3]
>>> alias_1 = list_1
>>> del alist_1[:]
>>> list_1
[]
>>> alias_1
[]

Однако a = [] создает новый список и присваивает его a:

>>> list_2 = [1,2,3]
>>> alias_2 = list_2
>>> list_2 = []
>>> list_2
[]
>>> alias_2
[1, 2, 3]

Если вы хотите более подробное обсуждение имен и ссылок в Python, я настоятельно рекомендую Нед Батчелдерссообщение в блоге «Факты и мифы об именах и значениях Python» .

Лучшее решение?

В большинстве случаев, когда у вас есть несколько переменных, которые принадлежат друг другу, я бы использовал класс дляих.Тогда вместо reset вы можете просто создать новый экземпляр и поработать с ним:

class FourLists:
    def __init__(self):
        self.a = []
        self.b = []
        self.c = []
        self.d = []

Затем вы можете создать новый экземпляр и работать с атрибутами этого экземпляра:

>>> state = FourLists()
>>> state.a
[]
>>> state.b.append(10)
>>> state.b.extend([1,2,3])
>>> state.b
[10, 1, 2, 3]

Тогда, если вы хотите сбросить состояние, вы можете просто создать новый экземпляр:

>>> new_state = FourLists()
>>> new_state.b
[]
0 голосов
/ 08 февраля 2019

Вторая функция (с a = [] и т. Д.) Инициализирует 4 новых списка с локальной областью действия (внутри функции).Это не то же самое, что удаление содержимого списка.

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