Cách cho phép phương thức list append () trả về danh sách mới


82

Tôi muốn làm một cái gì đó như thế này:

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

Rất tiếc, phần nối danh sách không trả về danh sách đã sửa đổi.

Vì vậy, làm thế nào tôi có thể cho phép appendtrả lại danh sách mới?

Câu trả lời:


139

Không sử dụng nối thêm mà thay vào đó là nối:

yourList = myList + [40]

Điều này trả về một danh sách mới ; myListsẽ không bị ảnh hưởng. Nếu bạn cần phải có myListảnh hưởng cũng như sử dụng bằng .append()mọi cách, sau đó chỉ định yourListriêng từ (bản sao của) myList.


2
điều gì sẽ là lý do đằng sau việc append()quay trở lại Nonethay vì cùng một danh sách? Nó sẽ vi phạm nguyên tắc thiền nào?
Ciprian Tomoiagă

3
@CiprianTomoiaga: xem en.wikipedia.org/wiki/Command%E2%80%93query_separation ; list.appendlà một lệnh, không phải là một truy vấn.
Martijn Pieters

2
@CiprianTomoiaga: cũng xem email này từ Python BDFL .
Martijn Pieters

2
@Dieblitzen: đúng, vì vậy OCaml sử dụng danh sách được liên kết và kết nối chúng. Danh sách Python không phải là bất biến vì vậy bạn không thể làm điều đó với những danh sách đó và hơn nữa, mọi thứ khác đều có thể thay đổi được . Trong khi danh sách OCaml chứa các đối tượng bất biến, trong Python, nội dung của các đối tượng bất biến như bộ giá trị vẫn có thể thay đổi được, vì vậy bạn không thể chia sẻ nội dung với các vùng chứa khác khi nối.
Martijn Pieters

2
@Dieblitzen: đó là lý do tại sao trong Python, để hoạt động nối có hiệu lực, bạn phải tạo một bản sao cạn và trả thời gian O (N). Tôi nên nói rõ ràng hơn, xin lỗi.
Martijn Pieters

21

Trong python 3, bạn có thể tạo danh sách mới bằng cách giải nén danh sách cũ và thêm phần tử mới:

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

khi bạn làm:

myList + [40]

Bạn thực sự có 3 danh sách.


1
Và đó là một chút nhanh hơn
aerobiomat

6

list.appendlà một cài đặt sẵn và do đó không thể thay đổi. Nhưng nếu bạn sẵn sàng sử dụng thứ gì đó khác append, bạn có thể thử +:

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]

Tất nhiên, nhược điểm của điều này là một danh sách mới được tạo ra sẽ mất nhiều thời gian hơn append

Hi vọng điêu nay co ich


Nhưng built-in có thể được subclassed và sau đó bất cứ điều gì đi :)
Marcin Wyszynski

@MarcinWyszynski: có, nhưng chúng chỉ có thể được sửa đổi trong lớp con. Việc xây dựng trong phương pháp của một built-in đối tượng / lớp hiếm khi có thể ghi đè, nếu bao giờ hết
inspectorG4dget

3
Đối với sự tỉnh táo của mình và của đồng nghiệp của bạn, bạn nên không bao giờ làm điều đó :)
Marcin Wyszynski

2

Bạn có thể phân lớp loại danh sách dựng sẵn và xác định lại phương thức 'append'. Hoặc tốt hơn nữa, hãy tạo một cái mới sẽ làm những gì bạn muốn nó làm. Dưới đây là mã cho phương thức 'nối thêm' được xác định lại.

#!/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()

Hy vọng rằng sẽ giúp.


2

Hãy thử sử dụng itertools.chain(myList, [40]). Điều đó sẽ trả về một trình tạo dưới dạng một chuỗi, thay vì phân bổ một danh sách mới. Về cơ bản, điều đó trả về tất cả các phần tử từ tệp có thể lặp đầu tiên cho đến khi hết, sau đó chuyển sang tệp có thể lặp tiếp theo, cho đến khi hết tất cả các tệp lặp.


1

Chỉ để mở rộng câu trả lời của Storstamp

Bạn chỉ cần thực hiện myList.append (40)

Nó sẽ nối nó vào danh sách ban đầu, bây giờ bạn có thể trả về biến chứa danh sách ban đầu.

Nếu bạn đang làm việc với danh sách rất lớn, đây là cách để đi.


-4

Bạn chỉ cần thực hiện myList.append (40)

Nó sẽ nối nó vào danh sách ban đầu, không trả lại một danh sách mới.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.