2016-07-23 7 views
1

オブジェクトはitemsというリストを含むデコードされたjsonオブジェクトです。pythonでenumerate()を使用するとリストから要素を削除します

obj = json.loads(response.body_as_unicode()) 

for index, item in enumerate(obj['items']): 
    if not item['name']: 
     obj['items'].pop(index) 

特定の条件が満たされた場合、これらのアイテムを繰り返し処理してアイテムを削除します。しかし、これは期待どおりに動作していません。いくつかの調査の後、私は、リストからアイテムを削除することができないと同時に、このリストをPythonで繰り返すことができないことを発見しました。しかし私は私の問題に上記の解決策を適用することはできません。

obj = json.loads(response.body_as_unicode()) 
items = obj['items'][:] 

for index, item in enumerate(obj['items']): 
    if not item['name']: 
     obj['items'].remove(item) 

しかし、これは名前を持たないアイテムだけでなく、すべてのアイテムを削除します。任意のアイデアをどのようにこれを解決するには?

+1

2番目のケースで 'for index、item in enumerate(items)'と書いてあると思います。 –

答えて

5

反復処理中にリストから項目を削除しないでください。反復インデックスは削除された要素を考慮して更新されないため、反復はskip itemsになります。

代わりに、は、フィルター付きlist comprehensionで、リストマイナスあなたが削除したい項目を再構築:

obj['items'] = [item for item in obj['items'] if item['name']] 

またはウォンを取り除くように、反復処理するために最初のリストのコピーを作成します

for item in obj['items'][:]: # [:] creates a copy 
    if not item['name']: 
     obj['items'].remove(item) 

あなたはコピーを作成しましたが、その後はオベをループすることにより、コピーを無視「tは反復変更しますrあなたがまだ削除しているリスト。

2

whileループを使用して、あなたがそれを必要とイテレータを変更:forループ反復変数に変更することができないという

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

# remove all items that are smaller than 5 
index = 0 
# while index in range(len(obj)): improved according to comment 
while index < len(obj): 
    if obj[index] < 5: 
     obj.pop(index) 
     # do not increase the index here 
    else: 
     index = index + 1 

print obj 

注意を。反復範囲内の次の値に常に設定されます。したがって、問題はenumerate関数ではなく、forループです。

今後、検証可能な例を提供してください。この例ではjsonオブジェクトを使用していますが、このオブジェクトを持たないため意味がありません。

+0

非常に冗長で(特にPython 2で非常にコストがかかる) '範囲内インデックス(len(obj) ) '?なぜ単に 'index

+0

私はそれが質問の詳細だと言います。不可欠な部分は、whileとforループの違いと、リスト項目がポップされたときのwhileループのイテレータの処理です。しかしあなたは正しいです:あなたの提案はその詳細を改善します。 –

関連する問題