Як дозволити методу list append () повертати новий список


86

Я хочу зробити щось подібне:

myList = [10, 20, 30]
yourList = myList.append(40)

На жаль, додаток списку не повертає змінений список.

Отже, як я можу дозволити appendповернути новий список?

Відповіді:


149

Натомість не використовуйте додаток, а конкатенацію:

yourList = myList + [40]

Це повертає новий список; myListце не вплине. Якщо вам також потрібно myListвплинути , будь-яким чином скористайтеся .append(), тоді призначте yourListокремо від (копія) myList.


3
що могло б бути обґрунтуванням append()повернення Noneзамість того самого списку? Який принцип дзен він би порушив?
Ciprian Tomoiagă

3
@CiprianTomoiaga: см en.wikipedia.org/wiki/Command%E2%80%93query_separation ; list.appendце команда, а не запит.
Мартін Пітерс

2
@CiprianTomoiaga: також перегляньте цей електронний лист від Python BDFL .
Мартін Пітерс

2
@Dieblitzen: так, отже, OCaml використовує зв’язані списки та з’єднує їх. Списки Python не є незмінними, тому ви не можете цього робити, а крім того, все інше може бути змінним . Хоча список OCaml містить незмінні об'єкти, у Python вміст незмінних об'єктів, таких як кортежі, все ще може бути змінним, тому ви не можете ділитися вмістом з іншими контейнерами при конкатенації.
Мартін Пітерс

2
@Dieblitzen: саме тому в Python, щоб операція конкатенації була дійсною, ви повинні створити неглибоку копію та заплатити O (N) час. Я повинен був бути більш чітким, вибачте.
Мартін Пітерс

22

У python 3 ви можете створити новий список, розпакувавши старий і додавши новий елемент:

a = [1,2,3]
b = [*a,4] # b = [1,2,3,4] 

коли ви робите:

myList + [40]

Ви насправді маєте 3 списки.


1
І це трохи швидше
aerobiomat

6

list.appendє вбудованим і тому не може бути змінений. Але якщо ви бажаєте використати щось інше append, ви можете спробувати +:

In [106]: myList = [10,20,30]

In [107]: yourList = myList + [40]

In [108]: print myList
[10, 20, 30]

In [109]: print yourList
[10, 20, 30, 40]

Звичайно, мінусом цього є те, що створюється новий список, який займає набагато більше часу, ніж append

Сподіваюся, це допомагає


Але вбудований можна перекласифікувати, і тоді все що завгодно :)
Marcin Wyszynski

@MarcinWyszynski: так, але їх можна змінити лише в межах підкласу. Вбудований метод вбудованого об'єкта / класу рідко можна замінити, якщо взагалі
інспекторG4dget

3
За свою власну розсудливість та розум своїх колег ніколи не слід цього робити :)
Марцін Вишинський

2

Ви можете підкласувати вбудований тип списку та перевизначити метод „додати”. Або ще краще, створити нову, яка буде робити те, що ти хочеш. Нижче наведено код для перевизначеного методу "додати".

#!/usr/bin/env python

class MyList(list):

  def append(self, element):
    return MyList(self + [element])


def main():
  l = MyList()
  l1 = l.append(1)
  l2 = l1.append(2)
  l3 = l2.append(3)
  print "Original list: %s, type %s" % (l, l.__class__.__name__)
  print "List 1: %s, type %s" % (l1, l1.__class__.__name__)
  print "List 2: %s, type %s" % (l2, l2.__class__.__name__)
  print "List 3: %s, type %s" % (l3, l3.__class__.__name__)


if __name__ == '__main__':
  main()

Сподіваюся, що це допомагає.


2

Спробуйте використовувати itertools.chain(myList, [40]). Це поверне генератор як послідовність, а не виділить новий список. По суті, це повертає всі елементи з першого ітеративного, поки він не буде вичерпаний, а потім переходить до наступного ітерабельного, поки всі ітерабельні не будуть вичерпані.


1

Просто, щоб розширити відповідь Storstamp

Вам потрібно лише зробити myList.append (40)

Він додасть його до вихідного списку, тепер ви можете повернути змінну, що містить оригінальний список.

Якщо ви працюєте з дуже великими списками, це шлях.


-5

Вам потрібно лише зробити myList.append (40)

Він додасть його до вихідного списку, а не поверне новий.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.