値によってリスト要素を削除する簡単な方法はありますか?


942
a = [1, 2, 3, 4]
b = a.index(6)

del a[b]
print(a)

上記は次のエラーを示しています:

Traceback (most recent call last):
  File "D:\zjm_code\a.py", line 6, in <module>
    b = a.index(6)
ValueError: list.index(x): x not in list

だから私はこれをしなければなりません:

a = [1, 2, 3, 4]

try:
    b = a.index(6)
    del a[b]
except:
    pass

print(a)

しかし、これを行う簡単な方法はありませんか?


14
リストの6のインデックスを計算します。しかし、6はリストに含まれていません...では、何が起こるはずですか?:)
Johannes Charra

5
コードはdelステートメントに到達しないため、これはリスト内の値の削除とは関係ありません。「リストにない値のインデックスを取得するにはどうすればよいですか。明らかな答え-できません。」
Dave Kirby

57
@デイブまあ、そうではありません。存在しないアイテムのインデックスを取得しないように、アイテムが存在するかどうかに関係なく、アイテムをリストから削除したいと考えています。質問はよく聞かれます。
ibz

要点は別ですが、ベアexceptは悪い習慣です。except Exception少なくとも使用してください。
wjandrea

回答:


1564

リスト内の要素の最初の出現を削除するには、単に次を使用しますlist.remove

>>> a = ['a', 'b', 'c', 'd']
>>> a.remove('b')
>>> print(a)
['a', 'c', 'd']

要素のすべての出現を削除するわけではないことに注意してください。そのためにリスト内包表記を使用してください。

>>> a = [10, 20, 30, 40, 20, 30, 40, 20, 70, 20]
>>> a = [x for x in a if x != 20]
>>> print(a)
[10, 30, 40, 30, 40, 70]

144
要素がリストにない場合は失敗します。:)
ibz

21
要素がリストにない場合でも、@ ibzリスト内包化は失敗しませんか?
IsaacS 2013

76
スキミングを明確にするために、ValueError例外を発生させるという意味で「失敗」します。
Casey Falk 14

10
リスト内包表記はリスト参照を変更するため、参照のコピーがどこかにある場合、削除は行われません。
Sebastien 2015年

removeそれはO(n)の複雑さは何ですか?
Rasmi Ranjan Nayak

184

通常、Pythonは、実行できないことを実行するように指示すると例外をスローするため、次のいずれかを実行する必要があります。

if c in a:
    a.remove(c)

または:

try:
    a.remove(c)
except ValueError:
    pass

例外は、期待どおりに適切に処理される限り、必ずしも悪いことではありません。


9
治療よりも予防​​が大切です。最初に例外条件を確認できる場合(例a)、そうする必要があります。
Gusdor

82
これは他の言語にも当てはまりますが、Pythonでは「許可よりも許しを求める方が簡単です」。docs.python.org/2/glossary.html#term-eafp
Dave Webb

6
@Gusdor:リストがスレッド間で共有されている場合a.remove(c)if c in aチェックにもかかわらず、とにかく失敗する可能性があります(チェックのac in aa.remove(c)呼び出しの前に別のスレッドで変更される可能性があります)。try/exceptまたは、ロックを使用して競合状態を回避できます。
jfs 2013

7
@JFSebastianスレッド間でリストが共有されていて、クリティカルセクションを適用していない場合、より大きな問題が発生します。
Gusdor 2013

4
@ Gusdor、Pythoniqueのイディオムは、チェックせずに試行し、発生した場合に例外をキャッチすることです。少し醜いですが、それはより効率的です(2つではなく1つのルックアップのみ)
Jeet

80

できるよ

a=[1,2,3,4]
if 6 in a:
    a.remove(6)

しかし、上記ではリスト内の6を2回検索する必要があるので、以下を試してください

try:
    a.remove(6)
except:
    pass

55

検討してください:

a = [1,2,2,3,4,5]

すべてのオカレンスを削除するには、Pythonのフィルター関数を使用できます。たとえば、次のようになります。

a = list(filter(lambda x: x!= 2, a))

したがって、のすべての要素が保持されますa != 2

アイテムを1つだけ取り出すには、

a.remove(2)

なぜfilter()別のもので包むのlist()ですか?マニュアルによると、それはすでにリストを返します。
オラフディーチェ、2015年

8
@OlafDietsche Python 3.xではフィルターオブジェクトを返します(2.xではリストを返します)。そのため、「a」をリストにキャストして機能を持たせる必要があります。
mathwizurd

17

これをその場で行う方法は次のとおりです(リスト内包なし)。

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]

とても賢いです-私はこれが本当に好きです-残念ながら、それは最も人気のある答えと同じくらい非効率的であるようです。ギルのソリューションは、削除したい値の発生が数個しかない巨大なリストに対して、実際にははるかに高速です。
Larold、2014

1
@Larold最速の方法は別の質問になります。私のお金は、一般的なケースではリストに含まれています。入力リストで値が頻繁に使用され、リスト内包表記が使用されていない場合、このソリューションは非常に適切に機能します。CythonでPypy、numpyデータを試してください。[ O(n*n)@Gill の答えは不必要です(1e6と1e12を比較してください–後者を危険にさらしたくない)。while 1: L.remove(value)戻り値は、CPythonの少数のリストまたは小さなリストでValueErrorうまく機能する可能性があり valueます。
jfs 2014

13

削除する値がわかっている場合は、次の簡単な方法を使用します(とにかく簡単に考えることができます)。

a = [0, 1, 1, 0, 1, 2, 1, 3, 1, 4]
while a.count(1) > 0:
    a.remove(1)

あなたが得るでしょう [0, 0, 2, 3, 4]


4
while 1 in a:ループ構造として使用してみませんか?
TerminalDilettante

12
これは、O(n^2)理解は次のようになりところO(n)
Mad Physicist

1
もちろん、@ MadPhysicistは正しく、TerminalDilettanteのバージョンは、パフォーマンスを気にしなくても、はるかにPython的です。2013年はPythonを習い始めたばかりで、最近では、自分が書いたことを恥ずかしく思うことがよくあります。
ギル2016

11

別の可能性は、セットがアプリケーションに適用可能な場合、リストの代わりにセットを使用することです。

データが順序付けられておらず、重複がない場合は、IE

my_set=set([3,4,2])
my_set.discard(1)

エラーはありません。

多くの場合、リストは、実際に順序付けされていないアイテムの便利なコンテナです。要素のすべての出現をリストから削除する方法を尋ねる質問があります。そもそもだまされたくない場合は、このセットも便利です。

my_set.add(3)

上からmy_setを変更しません。


10

他の多くの回答で述べられてlist.remove()いるValueErrorように、動作しますが、アイテムがリストになかった場合はをスローします。Python 3.4以降では、suppress contextmanagerを使用してこれを処理する興味深いアプローチがあります

from contextlib import suppress
with suppress(ValueError):
    a.remove('b')

8

リスト内の値を検索し、そのインデックス(存在する場合)を削除するには、リストのremoveメソッドを使用するだけです。

>>> a = [1, 2, 3, 4]
>>> try:
...   a.remove(6)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 3, 4]
>>> try:
...   a.remove(3)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 4]

これを頻繁に行う場合は、関数にまとめることができます。

def remove_if_exists(L, value):
  try:
    L.remove(value)
  except ValueError:
    pass

8

この例は高速で、リストから値のすべてのインスタンスを削除します。

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]

2
これを行う場合は、本当にbreakオンにする必要がありますexcept ValueError
Anthon


7

要素が異なる場合は、単純なセットの違いで十分です。

c = [1,2,3,4,'x',8,6,7,'x',9,'x']
z = list(set(c) - set(['x']))
print z
[1, 2, 3, 4, 6, 7, 8, 9]

2
要素が異なり、順序を気にしない場合
トムジッチ

2

.popも使用できます。

>>> lst = [23,34,54,45]
>>> remove_element = 23
>>> if remove_element in lst:
...     lst.pop(lst.index(remove_element))
... 
23
>>> lst
[34, 54, 45]
>>> 

2

削除する要素以外のすべてにインデックスを付けて、リストを上書きします

>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]

2

forループと条件:

def cleaner(seq, value):    
    temp = []                      
    for number in seq:
        if number != value:
            temp.append(number)
    return temp

そして、全部ではなく一部を削除したい場合:

def cleaner(seq, value, occ):
    temp = []
    for number in seq:
        if number == value and occ:
            occ -= 1
            continue
        else:
            temp.append(number)
    return temp


1

たとえば、xからすべて1を削除したいとします。これは私がそれについて行く方法です:

x = [1, 2, 3, 1, 2, 3]

今、これは私の方法の実用的な使用です:

def Function(List, Unwanted):
    [List.remove(Unwanted) for Item in range(List.count(Unwanted))]
    return List
x = Function(x, 1)
print(x)

そして、これは一行の私のメソッドです:

[x.remove(1) for Item in range(x.count(1))]
print(x)

どちらもこれを出力として生成します:

[2, 3, 2, 3, 2, 3]

お役に立てれば。PS、これはバージョン3.6.2で記述されているため、古いバージョンに合わせて調整する必要がある場合があります。


1

多分あなたの解決策はintで動作しますが、それは私には辞書で動作しません。

一方で、remove()は私にはうまくいきませんでした。しかし、おそらくそれは基本的なタイプで動作します。次のコードは、オブジェクトリストからアイテムを削除する方法でもあると思います。

一方、「del」も適切に機能していません。私の場合、Python 3.6を使用しています。「del」コマンドを使用して「for」ビュークルのリストから要素を削除しようとすると、Pythonがプロセスのインデックスを変更し、時間の前にビュークルが途中で停止します。要素ごとに逆の順序で削除した場合にのみ機能します。このようにして、保留中の要素の配列インデックスを変更するときに、それを変更しないでください。

次に、私は使用しました:

c = len(list)-1
for element in (reversed(list)):
    if condition(element):
        del list[c]
    c -= 1
print(list)

ここで、 'list'は[{'key1':value1 '}、{' key2 ':value2}、{' key3 ':value3}、...]のようになります

また、列挙を使用して、より多くのpythonicを実行できます。

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)

0
arr = [1, 1, 3, 4, 5, 2, 4, 3]

# to remove first occurence of that element, suppose 3 in this example
arr.remove(3)

# to remove all occurences of that element, again suppose 3
# use something called list comprehension
new_arr = [element for element in arr if element!=3]

# if you want to delete a position use "pop" function, suppose 
# position 4 
# the pop function also returns a value
removed_element = arr.pop(4)

# u can also use "del" to delete a position
del arr[4]

0

これにより、のすべてのインスタンスが"-v"配列から削除され、sys.argvインスタンスが見つからなかった場合でも問題はありません。

while "-v" in sys.argv:
    sys.argv.remove('-v')

実際のコードは、次のファイルで確認できますspeechToText.py

$ python speechToText.py -v
['speechToText.py']

$ python speechToText.py -x
['speechToText.py', '-x']

$ python speechToText.py -v -v
['speechToText.py']

$ python speechToText.py -v -v -x
['speechToText.py', '-x']

-1

これは私の答え、ちょうど使用されている間するために

def remove_all(data, value):
    i = j = 0
    while j < len(data):
        if data[j] == value:
            j += 1
            continue
        data[i] = data[j]
        i += 1
        j += 1
    for x in range(j - i):
        data.pop()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.