Подтвердить что ты не робот

Добавление элемента в списки в понимании списка

У меня есть список, скажем, a = [[1,2],[3,4],[5,6]]

Я хочу добавить строку 'a' к каждому элементу в списке a.

Когда я использую:

 a = [x.append('a') for x in a] 

он возвращает [None,None,None].

Но если я использую:

a1 = [x.append('a') for x in a]

то он делает что-то нечетное.

a, но не a1 - [[1,2,'a'],[3,4,'a'],[5,6,'a']].

Я не понимаю, почему первый вызов возвращает [None, None, None], а не почему второе изменение на a вместо a1.

4b9b3361

Ответ 1

list.append мутирует сам список и возвращает None. Перечисление списков заключается в сохранении результата, который не является тем, что вы хотите в этом случае, если хотите просто изменить исходные списки.

>>> x = [[1, 2], [3, 4], [5, 6]]
>>> for sublist in x:
...     sublist.append('a')
...
>>> x
[[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']]

Ответ 2

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

Но есть хитрость, которую я использую, когда хочу сделать что-то функционально *, изменяя существующие объекты (вместо того, чтобы создавать новые, в этом случае используя a=[x + ['a'] for x in a], или в частности, x + ['a']).

Итак, если вы достаточно смелы, вы также можете сделать это:

>>> a=[[1,2],[3,4],[5,6]]
>>> a=[x.append('a') or x for x in a]
>>> a
[[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']]

Это работает, потому что append возвращает None и продолжает or продолжает поиск значения true-y, которым является x (это list по крайней мере, с тем, что было добавлено к нему).

Зачем мне это вообще нужно?

Допустим, у вас есть список, и вы хотите вставить некоторых его членов в новый список и соответственно обновить ссылки:

Итак, у вас есть список all:

>>> all = [[], [], [], []]

Некоторые из них вставлены и обновлены в новый список x:

>>> x = [i.append('x') or i for i in all[:2]]
>>> x
[['x'], ['x']]

Некоторые из all также вставляются и обновляются в список y:

>>> y = [i.append('y') or i for i in all[1:3]]

all обновляется:

>>> all
[['x'], ['x', 'y'], ['y'], []]

Но x также обновляется:

>>> x
[['x'], ['x', 'y']]

И y генерируется, как и ожидалось:

>>> y
[['x', 'y'], ['y']]

В целом, для простых задач я бы рекомендовал явно использовать цикл for. Это то, что считается питоническим.

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

def more_functional_append(self, x):
    self.append(x)
    return self
  • Функциональное программирование основано на том, что каждое утверждение делает по существу одну вещь и не имеет побочных эффектов (то есть не изменяет и не возвращает). append не очень функционален, поскольку он мутирует список (чисто функциональное программирование имеет только неизменяемые объекты) и не возвращает результат для передачи другим действиям (функциям). Используя концепции функционального программирования, вы можете создавать большие однострочные тексты, которые никто не может прочитать, также известные как "безопасность работы" или "плохой код".

Ответ 3

В первом случае причина, по которой он возвращает [None, None, None], заключается в том, что функция list.append возвращает None и то, что она хранит в списке.

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

Что вам нужно - это оператор app-приложения, который не используется, например +. т.е. [x + ['a'] for x in a].

Ответ 4

(Это комбинация ответов Майка Грэма и сикоры):

Если вы просто хотите изменить значения на месте, попробуйте регулярный цикл for, а не список:

for sublist in a:
    sublist.append('a')

Если вы хотите оставить одного и поместить результат в a1:

a1 = [sublist + ['a'] for sublist in a]

Как они объяснили, append изменяет список, но возвращает None, а + оставляет список один, но возвращает новый, добавленный список.

Ответ 5

Вы можете использовать добавление в списки, например:

a = [x + ['a'] for x in a] 

Это дает желаемый результат для. В этом случае можно сделать его более эффективным, назначив ['a'] имени переменной перед циклом, но это зависит от того, что вы хотите сделать.

Ответ 6

оставьте a = и используйте побочный эффект на a:

[x.append('a') for x in a] 
print a

Ответ 7

В первом назначении значения вашего списка понимания Ошибка атрибута, объект 'NoneType' не имеет атрибута 'append', помогает объяснить, почему ваш список, a, будет загружен None (s). Чтобы заставить консоль выдавать ошибку, я использовал x в качестве переменной для понимания списка, а также в качестве итератора.

Traceback (most recent call last):
x = [x.append('a') for x in a]
AttributeError: 'NoneType' object has no attribute 'append'

Затем я вернулся к a для x, и он бросил ту же ошибку.

Traceback (most recent call last):
a = [x.append('a') for x in a]
AttributeError: 'NoneType' object has no attribute 'append'