list append()メソッドが新しいリストを返すことを許可する方法


86

私はこのようなことをしたい:

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

残念ながら、listappendは変更されたリストを返しません。

では、どうすればappend新しいリストを返すことができますか?

回答:


149

追加ではなく連結を使用してください。

yourList = myList + [40]

これにより、新しいリストが返されます。myList影響を受けません。あなたがしている必要がある場合にmyList影響を受けるだけでなく使用するか.append()、いずれにせよ、その後割り当てるyourList(のコピー)とは別にmyList


2
同じリストの代わりにappend()戻る理由は何Noneでしたか?どの禅の原則に違反しますか?
シプリアンTomoiagă

3
@CiprianTomoiaga:en.wikipedia.org/wiki/Command%E2%80%93query_separationを参照してください; list.appendはコマンドであり、クエリではありません。
MartijnPieters

2
@CiprianTomoiaga:PythonBDFLからのこのメールもご覧ください。
MartijnPieters

2
@Dieblitzen:そうですね、OCamlはリンクリストを使用してそれらを接続します。Pythonリストは不変ではないため、Pythonリストを使用してそれを行うことはできません。さらに、他のすべてを変更可能にすることができます。OCamlリストには不変オブジェクトが含まれていますが、Pythonでは、タプルなどの不変オブジェクトのコンテンツは引き続き変更可能であるため、連結時に他のコンテナーとコンテンツを共有することはできません。
MartijnPieters

2
@Dieblitzen:Pythonで連結操作を有効にするには、浅いコピーを作成し、O(N)時間を支払う必要があるのはそのためです。もっとはっきりさせてごめんなさい。
MartijnPieters

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 2012年

@MarcinWyszynski:はい。ただし、変更できるのはサブクラス内のみです。組み込みオブジェクト/クラスの組み込みメソッドが上書きされることはめったにありません
inspectorG4dget

3
あなた自身とあなたの同僚の正気のために、あなたは決してそれをするべきではありません:)
Marcin Wyszynski 2012年

2

組み込みリストタイプをサブクラス化し、「append」メソッドを再定義できます。またはさらに良いことに、あなたがやりたいことをする新しいものを作成してください。以下は、再定義された「append」メソッドのコードです。

#!/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)を実行するだけで済みます

新しいリストを返すのではなく、元のリストに追加します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.