Pythonのリストメソッドの追加と拡張の違いは何ですか?


回答:


5253

append:オブジェクトを最後に追加します。

x = [1, 2, 3]
x.append([4, 5])
print (x)

あなたにあげる: [1, 2, 3, [4, 5]]


extend:iterableから要素を追加することによってリストを拡張します。

x = [1, 2, 3]
x.extend([4, 5])
print (x)

あなたにあげる: [1, 2, 3, 4, 5]


122
extendと単純に加算演算子を使用することの違いは何ですか-上記の例では、x = x + [4, 5]
Rohan、2017年

303
実際にあります大きな違いは - x + [4, 5]-あなたのxに割り当てられた新しいリスト与えx.extend()突然変異し、元のリストを。以下の回答で詳しく説明します。
アーロンホール

@AaronHall @Rohanですが、と同じx += [4,5]です。
Astitva Srivastava

1
@AstitvaSrivastava実際、拡張はバイトコードの点で高速だと思います
MilkyWay90

1
使用時のキーワードappendObjectです。使用extendして辞書を渡すと、ハッシュ全体ではなくキーが配列の最後に追加されます。
アンソニー

640

append要素をリストに追加しextend、最初のリストを別のリスト(または、必ずしもリストではない別の反復可能オブジェクト)と連結します。

>>> li = ['a', 'b', 'mpilgrim', 'z', 'example']
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']

>>> li.append("new")
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']

>>> li.append(["new", 2])
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]

>>> li.insert(2, "new")
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]

>>> li.extend(["two", "elements"])
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2], 'two', 'elements']

490

リストメソッドの追加と拡張の違いは何ですか?

  • append引数を単一の要素としてリストの最後に追加します。リスト自体の長さは1つ増えます。
  • extend引数を反復処理して、各要素をリストに追加し、リストを拡張します。リストの長さは増加しますが、反復可能な引数に多くの要素が含まれていました。

append

このlist.appendメソッドは、リストの最後にオブジェクトを追加します。

my_list.append(object) 

オブジェクトが何であれ、数値、文字列、別のリスト、または何か他のものであるかに関係なく、それはmy_listリストの単一のエントリとして末尾に追加されます。

>>> my_list
['foo', 'bar']
>>> my_list.append('baz')
>>> my_list
['foo', 'bar', 'baz']

したがって、リストはオブジェクトであることに注意してください。別のリストをリストに追加した場合、最初のリストはリストの最後にある単一のオブジェクトになります(これは必要なものではない可能性があります)。

>>> another_list = [1, 2, 3]
>>> my_list.append(another_list)
>>> my_list
['foo', 'bar', 'baz', [1, 2, 3]]
                     #^^^^^^^^^--- single item at the end of the list.

extend

このlist.extendメソッドは、イテラブルから要素を追加してリストを拡張します。

my_list.extend(iterable)

したがって、extendを使用すると、反復可能オブジェクトの各要素がリストに追加されます。例えば:

>>> my_list
['foo', 'bar']
>>> another_list = [1, 2, 3]
>>> my_list.extend(another_list)
>>> my_list
['foo', 'bar', 1, 2, 3]

文字列は反復可能であることを覚えておいてください。そのため、文字列でリストを拡張する場合、文字列を反復するときに各文字を追加します(これは希望どおりではない場合があります)。

>>> my_list.extend('baz')
>>> my_list
['foo', 'bar', 1, 2, 3, 'b', 'a', 'z']

演算子のオーバーロード、__add__+)および__iadd__+=

両方++=演算子は、のために定義されていますlist。それらは意味的には拡張に似ています。

my_list + another_list メモリ内に3番目のリストを作成するため、その結果を返すことができますが、2番目の反復可能オブジェクトがリストである必要があります。

my_list += another_listリストをインプレース(これインプレース演算子であり、リストは変更可能なオブジェクトです)を変更するので、新しいリストを作成しません。また、2番目の反復可能オブジェクトはどのような種類の反復可能でもかまいません。

混乱しないでください- my_list = my_list + another_listと同等ではありません+= -my_listに割り当てられたまったく新しいリストを提供します。

時間の複雑さ

Appendには一定の時間の複雑さ O(1)があります。

Extendには時間の複雑さ、O(k)があります。

複数の呼び出しを繰り返すとappend複雑さが増し、extendのそれと同等になります。extendの反復はCで実装されているため、反復可能オブジェクトからリストに連続する項目を追加する場合は常に高速になります。

パフォーマンス

appendを使用すると、extendと同じ結果を得ることができるので、何がよりパフォーマンスが高いのか疑問に思われるかもしれません。次の関数は同じことを行います。

def append(alist, iterable):
    for item in iterable:
        alist.append(item)

def extend(alist, iterable):
    alist.extend(iterable)

では、時間を計りましょう:

import timeit

>>> min(timeit.repeat(lambda: append([], "abcdefghijklmnopqrstuvwxyz")))
2.867846965789795
>>> min(timeit.repeat(lambda: extend([], "abcdefghijklmnopqrstuvwxyz")))
0.8060121536254883

タイミングに関するコメントへの対応

コメント者は言った:

完璧な答えです。要素を1つだけ追加して比較するタイミングを逃してしまいます

意味的に正しいことを行います。イテラブル内のすべての要素を追加する場合は、を使用しますextend。要素を1つだけ追加する場合は、append

それでは、これが時間内にどのように機能するかを確認するための実験を作成してみましょう。

def append_one(a_list, element):
    a_list.append(element)

def extend_one(a_list, element):
    """creating a new list is semantically the most direct
    way to create an iterable to give to extend"""
    a_list.extend([element])

import timeit

そして、extendを使用するだけでイテラブルを作成する方法から抜け出すことは、(マイナー)時間の無駄であることがわかります。

>>> min(timeit.repeat(lambda: append_one([], 0)))
0.2082819009956438
>>> min(timeit.repeat(lambda: extend_one([], 0)))
0.2397019260097295

これから、追加する要素が1つextendしかない場合は、使用しても何も得られないことがわかります。

また、これらのタイミングはそれほど重要ではありません。私は物事やっている、Pythonで、意味的に正しいことをやってポイントを作るためにそれらを示しています右の道を™。

2つの比較可能な操作でタイミングをテストして、あいまいな結果または逆の結果が得られる可能性があると考えられます。意味的に正しいことに集中するだけです。

結論

私たちは、それが見extend意味的に明確であり、それはより速くよりもはるかに実行することができappendあなたがリストへのiterableの各要素を追加しようとするとき。

リストに追加する要素が1つしかない場合(反復可能でない場合)は、を使用しますappend


1
@Aaron Hallタイミングに関するアルゴリズムの1つの小さなコメント。リストの作成も含まれるため、「extend_one」は「わずかに間違った」時間を返すことがあります。より厳密にしたい場合は、アイテムを変数(ex1 = 0およびex2 = [0])として作成し、これらの変数を渡すことをお勧めします。
ilias iliadis 2018年

19
確かに完璧な答え。l1 += l2vsのパフォーマンスはどうl1.extend(l2)ですか?
Jean-Francois T.

6
@ Jean-FrancoisT .: l1 += l2そして、l1.extend(l2)最終的に同じコード(のlist_extend関数listobject.c)を実行します。唯一の違いは次のとおりです。1。+=再割り当てl1listsはそれ自体に割り当てられますが、その後は同じオブジェクトではない不変タイプをサポートします)。これは、l1が実際に不変オブジェクトの属性である場合に違法になります。例えば、t = ([],)t[0] += lst一方で、失敗していましt[0].extend(lst)働くだろう。2. l1 += l2専用のバイトコードをl1.extend(l2)使用し、汎用のメソッドディスパッチを使用します。これは、+=より速くなりextendます。
ShadowRanger 2018

3
+=再割り当てl1しなければならないという事実は、場合extendによっては、左側の割り当てを戻さないことで、の遅いディスパッチが部分的または完全に埋め合わされることを意味します。例えば、場合list、オブジェクトの属性であり、self.l1 += l2そしてself.l1.extend(l2)私はPythonで同じ性能を持つ3.6実際の操作がよりようであるという理由だけで、インストールself.l1 = self.l1.__iadd__(l2)それは適度に高価実行しなければならない手段、STORE_ATTRそれself.l1.extend(l2)に持っていません。
ShadowRanger 2018

2
ローカルテストでの単純な比較:ローカル変数の場合(これ+=はを使用しているため、STORE_FAST非常に安価です)、追加される値がlist1つのアイテムを含む既存のものであり、操作が1000回繰り返さ+=れ、平均で約33 nsかかりました、extend78 nsかかったが、45 nsの差。場合l1(より高価必要がグローバルであるSTORE_GLOBAL)、その差は17ナノ秒に狭くなる。場合l1、実際にはlocal.l1(さらに高価必要STORE_ATTRの間に有意な差がない)+=extend(略同一のタイミングは、extend時々 WINS)。
ShadowRanger 2018

121

append 単一の要素を追加します。 extend要素のリストを追加します。

追加するリストを渡しても、要素が1つ追加されることに注意してください。

>>> a = [1, 2, 3]
>>> a.append([4, 5, 6])
>>> a
[1, 2, 3, [4, 5, 6]]

62

追加と拡張

ここに画像の説明を入力してください

追加を使用すると、リストを拡張する単一の要素を追加できます。

>>> a = [1,2]
>>> a.append(3)
>>> a
[1,2,3]

複数の要素を拡張する場合は、要素の1つの要素または1つのリストしか追加できないため、extendを使用する必要があります。

>>> a.append([4,5])
>>> a
>>> [1,2,3,[4,5]]

ネストされたリストを取得できるように

代わりに、extendを使用すると、次のように単一の要素を拡張できます

>>> a = [1,2]
>>> a.extend([3])
>>> a
[1,2,3]

または、別の方法として、追加から、リストを元のリストにネストせずに、一度により多くの要素を拡張します(これが名前拡張の理由です)。

>>> a.extend([4,5,6])
>>> a
[1,2,3,4,5,6]

両方の方法で1つの要素を追加する

ここに画像の説明を入力してください

appendとextendはどちらも、リストの最後に1つの要素を追加できますが、appendの方が簡単です。

1つの要素を追加

>>> x = [1,2]
>>> x.append(3)
>>> x
[1,2,3]

1つの要素を拡張する

>>> x = [1,2]
>>> x.extend([3])
>>> x
[1,2,3]

要素を追加しています...異なる結果

複数の要素に追加を使用する場合、要素のリストを引数として渡す必要があり、ネストされたリストを取得します!

>>> x = [1,2]
>>> x.append([3,4])
>>> x
[1,2,[3,4]]

代わりに、extendを使用すると、リストを引数として渡しますが、古い要素にネストされていない新しい要素を含むリストを取得します。

>>> z = [1,2] 
>>> z.extend([3,4])
>>> z
[1,2,3,4]

したがって、より多くの要素がある場合は、extendを使用して、より多くの項目を含むリストを取得します。ただし、リストを追加してもリストには要素が追加されませんが、コードの出力ではっきりとわかるように、ネストされたリストである1つの要素が追加されます。

ここに画像の説明を入力してください

ここに画像の説明を入力してください


61

次の2つのスニペットは、意味的に同等です。

for item in iterator:
    a_list.append(item)

そして

a_list.extend(iterator)

ループがCで実装されているため、後者の方が高速になる場合があります。


20
私のマシンでは、ループで追加するよりも拡張が約4倍高速です(ゼロの100ループでは16us対4us)
Alex L

6
extend()おそらく事前割り当てしますが、append()そうではない可能性があります。
Mad Physicist

@MadPhysicist:完全を期すために、一部のイテラブルが実装されていないため、適切に事前割り当てextend() できない場合があり__len__()ますが、あなたのように、試さない場合は驚くでしょう。アーロンの回答で指摘されているように、パフォーマンスの向上の一部は、Pythonではなく純粋なCで反復部分を実行することからも得られます
Soren Bjornstad

44

このappend()メソッドは、リストの最後に単一のアイテムを追加します。

x = [1, 2, 3]
x.append([4, 5])
x.append('abc')
print(x)
# gives you
[1, 2, 3, [4, 5], 'abc']

このextend()メソッドは1つの引数、リストを取り、引数の各項目を元のリストに追加します。(リストはクラスとして実装されます。リストを「作成する」とは、実際にはクラスをインスタンス化することです。そのため、リストにはそれを操作するメソッドがあります。)

x = [1, 2, 3]
x.extend([4, 5])
x.extend('abc')
print(x)
# gives you
[1, 2, 3, 4, 5, 'a', 'b', 'c']

Dive Into Pythonから。


反復可能ではないため、6だけで拡張することはできません。そして、あなたの例の2番目の出力は間違っています。'abc'はextend、1つの要素['abc'][1、2、3、4、5、 'abc'] を含むリストとして渡したため、単一の要素として追加されます。出力例を正しくするには、abc行を次のように変更しますx.extend('abc')。を削除するx.extend(6)か、に変更しx.extend([6])ます。
アネロイド2014

37

所定の位置に拡張する代わりに、「+」を使用して拡張を返すことができます。

l1=range(10)

l1+[11]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]

l2=range(10,1,-1)

l1+l2

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2]

同様に+=、インプレースの動作ですが、append&とわずかに異なりextendます。最大の違いの一つ+=からappendextend、それは、関数のスコープで使用されている場合で、参照このブログ記事を


「+」を使用して拡張を返すと、時間の複雑さに影響がありますか?
フランクリン

5
@franklin、詳細についてはこの回答を参照してください:stackoverflow.com/a/28119966/2230844
denfromufa

1
これが質問にどのように答えるかはわかりません
pppery 2018

22

append(object) -リストにオブジェクトを追加してリストを更新します。

x = [20]
# List passed to the append(object) method is treated as a single object.
x.append([21, 22, 23])
# Hence the resultant list length will be 2
print(x)
--> [20, [21, 22, 23]]

extend(list) -本質的に2つのリストを連結します。

x = [20]
# The parameter passed to extend(list) method is treated as a list.
# Eventually it is two lists being concatenated.
x.extend([21, 22, 23])
# Here the resultant list's length is 4
print(x)
[20, 21, 22, 23]

20

extend()イテレータ引数とともに使用できます。ここに例があります。次のようにして、リストのリストからリストを作成します。

から

list2d = [[1,2,3],[4,5,6], [7], [8,9]]

あなたが欲しい

>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9]

あなたはそうするのに使うかもしれitertools.chain.from_iterable()ません。このメソッドの出力はイテレータです。その実装は以下と同等です

def from_iterable(iterables):
    # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
    for it in iterables:
        for element in it:
            yield element

私たちの例に戻って、私たちはできる

import itertools
list2d = [[1,2,3],[4,5,6], [7], [8,9]]
merged = list(itertools.chain.from_iterable(list2d))

指名手配リストを取得します。

extend()イテレータの引数と同等に使用できる方法を次に示します。

merged = []
merged.extend(itertools.chain.from_iterable(list2d))
print(merged)
>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9]

2
この回答は、追加による拡張と対照的ではないため、質問に回答しません
pppery

19

これは、演算子appendと同等でextend+演算子を使用しています。

>>> x = [1,2,3]
>>> x
[1, 2, 3]
>>> x = x + [4,5,6] # Extend
>>> x
[1, 2, 3, 4, 5, 6]
>>> x = x + [[7,8]] # Append
>>> x
[1, 2, 3, 4, 5, 6, [7, 8]]

= +しないのはなぜですか?より簡潔
denfromufa

16

append():これは基本的に、1つの要素を追加するためにPythonで使用されます。

例1:

>> a = [1, 2, 3, 4]
>> a.append(5)
>> print(a)
>> a = [1, 2, 3, 4, 5]

例2:

>> a = [1, 2, 3, 4]
>> a.append([5, 6])
>> print(a)
>> a = [1, 2, 3, 4, [5, 6]]

extend():extend()は、2つのリストをマージするか、1つのリストに複数の要素を挿入するために使用されます。

例1:

>> a = [1, 2, 3, 4]
>> b = [5, 6, 7, 8]
>> a.extend(b)
>> print(a)
>> a = [1, 2, 3, 4, 5, 6, 7, 8]

例2:

>> a = [1, 2, 3, 4]
>> a.extend([5, 6])
>> print(a)
>> a = [1, 2, 3, 4, 5, 6]

12

ほのめかされているが説明されていない興味深い点は、拡張が追加よりも速いことです。内部に追加があるループについては、list.extend(processed_elements)で置き換えられると見なされます。

新しい要素を承認すると、リスト全体がメモリ内のより適切な場所に再配置される可能性があることに注意してください。一度に1つの要素を追加するためにこれが数回行われると、全体的なパフォーマンスが低下します。この意味で、list.extendは "" .join(stringlist)に類似しています。


12

Appendは、データ全体を一度に追加します。データ全体が、新しく作成されたインデックスに追加されます。一方、extendその名前が示すように、は現在の配列を拡張します。

例えば

list1 = [123, 456, 678]
list2 = [111, 222]

append我々が得ます:

result = [123, 456, 678, [111, 222]]

間にextend我々が得ます:

result = [123, 456, 678, 111, 222]

8

英語の辞書は単語appendを次のextendように定義します。

append:書かれたドキュメントの最後に(何か)を追加します。
拡大:大きくします。拡大または拡大


その知識で、今理解しましょう

1)との差appendextend

append

  • Pythonオブジェクトをそのまま追加しますをそのままリストの最後に(つまり、リストの最後の要素として)。
  • 結果のリストはネストされ、異種の要素(リスト、文字列、タプル、辞書、セットなど)を含む場合があります。

extend

  • 引数としてイテラブルを受け入れ、リストを大きくします。
  • 結果のリストは常に1次元のリスト(つまり、入れ子にならない)であり、を適用した結果として、異種の要素(文字、整数、浮動小数点など)が含まれる場合がありますlist(iterable)

2)との間の類似性appendextend

  • どちらも厳密に1つの引数を取ります。
  • どちらもリストをインプレースで変更します。
  • その結果、両方がを返しますNone

lis = [1, 2, 3]

# 'extend' is equivalent to this
lis = lis + list(iterable)

# 'append' simply appends its argument as the last element to the list
# as long as the argument is a valid Python object
list.append(object)

5

この質問に役立つサプリメントを作れることを願っています。たとえば、リストに特定のタイプのオブジェクトが格納されている場合、メソッドが適切でないInfo状況extendは次のとおりです。forループでInfoオブジェクトを毎回生成し、extendそれを使用してリストに格納すると、失敗します。例外は以下のようなものです:

TypeError: 'Info'オブジェクトは反復可能ではありません

ただし、このappend方法を使用すると、結果は問題ありません。extendメソッドを使用するたびに、常にそれをリストまたは他のコレクションタイプとして扱い、反復し、前のリストの後に配置します。明らかに、特定のオブジェクトは反復できません。


4

直感的に区別する

l1 = ['a', 'b', 'c']
l2 = ['d', 'e', 'f']
l1.append(l2)
l1
['a', 'b', 'c', ['d', 'e', 'f']]

それはl1彼女の体の内部を入れ子にしたようなものです。

# Reset l1 = ['a', 'b', 'c']
l1.extend(l2)
l1
['a', 'b', 'c', 'd', 'e', 'f']

それは、2人の別々の個人が結婚し、団結した家族を築くようなものです。

その上、私はあなたの参照のためにすべてのリストのメソッドの徹底的なチートシートを作ります。

list_methods = {'Add': {'extend', 'append', 'insert'},
                'Remove': {'pop', 'remove', 'clear'}
                'Sort': {'reverse', 'sort'},
                'Search': {'count', 'index'},
                'Copy': {'copy'},
                }

2

extend(L)指定されたリスト内のすべてのアイテムを追加することにより、リストを拡張しますL

>>> a
[1, 2, 3]
a.extend([4])  #is eqivalent of a[len(a):] = [4]
>>> a
[1, 2, 3, 4]
a = [1, 2, 3]
>>> a
[1, 2, 3]
>>> a[len(a):] = [4]
>>> a
[1, 2, 3, 4]

0

appendリストを(その場で)1つのitemだけ「拡張」し、単一のオブジェクトが(引数として)渡されます。

extend(引数として)渡さたオブジェクトに含まれているのと同じ数の項目で(所定の場所に)リストを「拡張」します。

これはstrオブジェクトを少し混乱させるかもしれません。

  1. 文字列を引数として渡す appendと、最後に単一の文字列アイテム extendが追加されますが、その文字列の長さと同じ数の「単一」の「str」アイテムが追加されます。
  2. 文字列のリストを引数として渡す場合: appendは最後に単一の「リスト」アイテム extendを追加し、渡されたリストの長さと同じ数の「リスト」アイテムを追加します。
def append_o(a_list, element):
    a_list.append(element)
    print('append:', end = ' ')
    for item in a_list:
        print(item, end = ',')
    print()

def extend_o(a_list, element):
    a_list.extend(element)
    print('extend:', end = ' ')
    for item in a_list:
        print(item, end = ',')
    print()
append_o(['ab'],'cd')

extend_o(['ab'],'cd')
append_o(['ab'],['cd', 'ef'])
extend_o(['ab'],['cd', 'ef'])
append_o(['ab'],['cd'])
extend_o(['ab'],['cd'])

生成する:

append: ab,cd,
extend: ab,c,d,
append: ab,['cd', 'ef'],
extend: ab,cd,ef,
append: ab,['cd'],
extend: ab,cd,

0

追加と拡張は、Pythonの拡張メカニズムの1つです。

追加:リストの最後に要素を追加します。

my_list = [1,2,3,4]

リストに新しい要素を追加するには、次のようにappendメソッドを使用できます。

my_list.append(5)

新しい要素が追加されるデフォルトの場所は常に(length + 1)の位置です。

挿入:挿入メソッドは、追加の制限を克服するために使用されました。insertを使用すると、新しい要素を挿入する正確な位置を明示的に定義できます。

insert(index、object)のメソッド記述子。これは2つの引数を取ります。1つは要素を挿入するインデックスで、もう1つは要素自体です。

Example: my_list = [1,2,3,4]
my_list[4, 'a']
my_list
[1,2,3,4,'a']

拡張:これは、2つ以上のリストを1つのリストに結合する場合に非常に役立ちます。拡張しないと、2つのリストを結合したい場合、結果のオブジェクトにはリストのリストが含まれます。

a = [1,2]
b = [3]
a.append(b)
print (a)
[1,2,[3]]

pos 2で要素にアクセスしようとすると、要素ではなくリスト([3])が取得されます。2つのリストを結合するには、appendを使用する必要があります。

a = [1,2]
b = [3]
a.extend(b)
print (a)
[1,2,3]

複数のリストに参加するには

a = [1]
b = [2]
c = [3]
a.extend(b+c)
print (a)
[1,2,3]

2
すでに何度も回答されている質問になぜ答えるのですか?この質問は10歳です...
マイク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.