2015-12-06 4 views
0

Вот проблема, которую я должен был сделать:list.append (another_list) vs list.append (another_list [:]) в python?

Мы собираемся реализовать очень полезную функцию, называемую группой.

Группа

принимает список вещей и возвращает список групп, где каждая группа формируется всеми одинаковыми последовательными элементами в списке.

Например:

группа ([1, 1, 1, 2, 3, 1, 1]) == [[1, 1, 1], [2], [3], [1 , 1]]

группа ([1, 2, 1, 2, 3, 3]) == [[1], [2], [1], [2], [3, 3]]

А вот мое первоначальное решение:

def group(int_list):  

group_list = [] 
current_list = [] 

for i in range(len(int_list)): 
    if int_list[i] not in current_list: 
     if len(current_list) != 0: 
      group_list.append(current_list) 
     del current_list[:] 
     current_list.append(int_list[i]) 
    else: 
     current_list.append(int_list[i])  

group_list.append(current_list) 

return group_list 

И выход я получаю:

[[1, 1], [1, 1], [1, 1], [1, 1]] 

Пройдя 30 минут, пытаясь разобраться в проблеме, я сменил 9-ю строчку с group_list.append(current_list) на group_list.append(current_list[:]) и на удивление магия работала. Я получил правильный вывод:

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

Так что я думаю, мой вопрос в чем разница между current_list и current_list[:]?

+0

Другой способ исправить исходный код - изменить 'del current_list [:]' на 'current_list = []', таким образом, в следующий раз, когда вы добавите 'current_list', это будет другой список (т. Е. Не нужно сделайте мелкую копию). – gatto

ответ

2

current_list[:] является мелкая копия из current_list; например,:.

В вашей функции, вы построение списка (текущей группы) в вещах ссылаются current_list. Когда вы закончите, вы добавите эту вещь в group_list, а затем сбросьте ее, удалив все ее содержимое (del current_list[:]). Мы должны помнить, что все в Python является ссылкой, поэтому, используя ваш первый код, group_list содержит несколько ссылок на тот же объект (вот почему ваш вывод выглядит как [[1, 1], [1, 1], [1, 1], [1, 1]]). Когда вы удаляете содержимое current_list и добавляете новые элементы позже, вы делаете это для каждого элемента group_list.

Используя созданный вами current_list[:] синтаксис, вы создаете копию current_list и добавляете это на group_list; эта копия не будет изменена позже, когда вы удалите содержимое current_list.

+0

Так это правильный способ сделать это? Просто добавив [:] –

+1

@BobbyBrown, похоже, консенсус заключается в том, что с точки зрения стиля кода более четкое создание мелких копий путем записи 'list (current_list)', чем 'current_list [:]'. Это просто эстетика; создание копий с помощью slice-оператора отлично работает. – wildwilhelm

1

Основным отличием является то, что current_list является ссылкой на список, а current_list [:] - это новый массив с элементами списка. Таким образом, используя первый, при изменении текущего списка, также изменяется список group_list. Другой способ, если вы измените текущий_list, group_list не будет изменен.

Смежные вопросы