2016-11-05 3 views
2

そのコードは数字のうち「袋」のリストをクリアします。数字が数字の後に続く場合、それは正しく機能しません。例えば8 数字の後に数字が続く場合はポップ()は表示されません

bag = ['apples', 1,'bananas', 'potatoes', 'tomatoes',2, 'chary',3, 'mo4ka', 7,8, 'candies', 'Main_TX'] 
list_n = [] 
x = 0 
for i in bag: 
    if isinstance(i, int): 
     list_n.append(i) 
     bag.pop(x) 
    x+=1 

print(list_n) 
print(bag) 

7.後の結果:

[1, 2, 3, 7] 
['apples', 'bananas', 'potatoes', 'tomatoes', 'chary', 'mo4ka', 8, 'candies', 'Main_TX'] 

答えて

4

は、あなたがそれを反復している間、リストを変更しようとしないでください。

list_n = [] 
new_bag = [] 
for x in bag: 
    # which_list = list_n if isinstance(x, int) else new_bag 
    # which_list.append(x) 
    if isinstance(x, int): 
     list_n.append(x) 
    else: 
     new_bag.append(x) 
bag = new_bag 
+0

ご回答いただきありがとうございます。 私はこの障害を克服することについて同じ方法を考えていました: それはうまくいきます。しかし、この初期のコードのこの動作は私にとって奇妙で、バグのように見えます。 bag = ['りんご'、1、 'バナナ'、 'トマト'、2、 'chary'、3、 'mo4ka'、7,8、 'キャンディーズ'、 'Main_TX'] list_n = [] list_a = [] iについて袋に: 場合でisinstance(I、INT): list_n.append(I)他 :list_a.append(I) プリント(list_n) プリント(list_a) print(bag) ' – zero

1

あなたはmodifying your list while iteratingです。これは予期しない動作につながります。

代わりに、リストの内包表記を使用することができます:あなたのコードが動作しない理由を

list_n = [e for e in bag if isinstance(e, int)] 
bag = [e for e in bag if not isinstance(e, int)] 

具体的な理由は、あなたがbag.pop(x)で、リスト内の次の項目を要素を削除するたびにがバックをシフトしてしまうことがあります1つのインデックス。しかし、for .. inループで使用されるイテレータは、このシフトについてを知ることができないため、next()関数を呼び出すと、基本的に1つの要素をスキップします。

ループの先頭の直後にprint(i)を追加すると、番号がリストからポップされるたびに、for .. inループ内の次のリストエントリがスキップされることがわかります(数値であるかどうかにかかわらず) 。それが数字でない場合は、文字列はリストに残っているはずなので、気づかないだけです。

+1

' map'は、各項目に適用された操作をラップするために、しばしばユーザ定義関数が必要であるため、リストの補完はより速く 'map'の代替手段です。単純にリストをフィルタリングしている場合は、リストを2回以上反復する必要があり、単一の 'for'ループを書くよりも遅くなります。 – chepner

+0

@chepnerこれは間違いなく真実であり、パフォーマンスが懸念される場合は、私自身もシングルループオプションを使用します。ただし、リストが大きすぎないか、パフォーマンスに問題がない限り、速度の違いは実際にはランタイム全体に影響を与えません。 – Keiwan

+0

"予期しない動作"はまさに私を得たものです。それは私には窮地に見える。番号が落ちるときを除いて、常にうまく動作します。そしてそれはちょっと奇妙です。 – zero

関連する問題