2016-10-22 12 views
1

このリンクから引用されていますhttp://www.python-course.eu/for_loop.php - これらの副作用を回避するために 次の例に見られるように、それは、スライス演算子を使用してコピーで作業するのが最善です:Pythonのリストでスライス演算子を使ってforループの副作用を避けるには?

colours = ["red"] 
for i in colours[:]: 
    if i == "red": 
     colours += ["black"] 
    if i == "black": 
     colours += ["white"] 
print colours 

出力は次のとおりです。

['red', 'black'] 

私の質問は:文colours[:]は色のリストのコピーを作成し、forループの代わりに、元のリストのコピー上で動作しますか?もしそうなら、元のカラーリストに["balck"]がどのように付加されていますか?

+1

はいあなたはまだ元のリストに追加しています。ループして追加する前に新しいコピーを作成してください。 –

+0

あなたがしようとしているものとまったく異なるので、完全なコードを追加してください。 –

答えて

3

声明colours[:]は、色リストのコピーを作成しない:はい。

とforループは元のリストの代わりにコピーで動作しますか?はい、しかし、あなたが "働いている"という意味に注意してください。変数iはリストcoloursのコピーからその値をとります。しかしながら、coloursへの参照は、の行のように、元のリストを参照しています。これはコードが望むものなので、うまく機能します。

もしそうなら、元のカラーリストに[balck]がどのように付加されていますか?これは、追加を行う行が元のリストを参照し、リストのコピーを参照しないためです。

+0

の意図と一致するように元のリストを繰り返し処理する必要がありますので、 'colors [:] + = [" black "]'と書くとコピーリストに追加されます。元のリストの効果?第二に、コピーを変更することはできますか? – dlpnewbie96

+0

'colors [:] + = [" black "]'と書くと、反復処理しているコピーではなく、新しいコピーに追加します。 – L3viathan

+0

@ dlpnrwbie96、新しいリストを作成する必要はありません、 'new = colors [:]'とnewに追加する –

2

colours[:]は元のリストのコピーを作成し、それを反復処理しますが、coloursは元のリストのままです。次のコードは同等のようになります。

copy = colours.copy() 
for i in copy: 
    if i == "red": 
     colours.append("black") # append is O(1) 
    if i == "black": 
     colours.append("white") 
+0

appendを使用してリストに追加 –

+1

@PadraicCunningham元のコードをそのままコピーしましたが、はい、変更されました。 – L3viathan

+0

コード –

1

これは、あなたが提供linkで参照しているコードです:リストの上にあなたのループ場合

、それはループ本体内のリストを変更しないことをお勧めします。あなたの例を与えるために、何が起こることができ、次の例を見て:

colours = ["red"] 
for i in colours: 
    if i == "red": 
     colours += ["black"] 
    if i == "black": 
     colours += ["white"] 
print colours 

「印刷色」で印刷されますか?次の例に見られるようにこれらの副作用を回避するために

['red', 'black', 'white'] 

、それは、スライス演算子を使用してコピーで作業するのが最善です:

colours = ["red"] 
for i in colours[:]: 
    if i == "red": 
     colours += ["black"] 
    if i == "black": 
     colours += ["white"] 
print colours 
Now the output looks like this: 
['red', 'black'] 

我々はまだ持っているかもしれません何かをした、私たちがしてはいけないこと。リストの色を変更しましたが、私たちの変更はもはやループに何の影響も与えませんでした。ループされる要素は、反復の間は同じままです。

ので:

colours = ["red"] 
for i in colours[:]: # iterates over a copy so we only evaluate what is in the list originally 
    if i == "red": 
     colours += ["black"] 
    if i == "black": 
     colours += ["white"] 
print(colours) # ["red", "black"] 

は今何のコピー:

colours = ["red"] 
for i in colours: 
    if i == "red": 
     colours += ["black"] # black gets added, colours -> ["red", "black"] 
    if i == "black": # now because of ^^, white gets added. 
     colours += ["white"] 
print(colours) # -> ['red', 'black', 'white'] 

今でも最悪の場合:

colours = ["red"] 
for i in colours: 
    if i == "red": 
     colours += ["red"] # red gets add, colours = ["red", "red"] 
          # 2nd iteration, red gets added, colours -> colours = ["red", "red", "red"] 
          # infinite loop.... 
    if i == "black": 
     colours += ["white"] 
print(colours) 

何をやっているが、例が何であるかを完全に違いはありません表示しようとしているので、それを反復しているリストに要素を追加しないようにしようとしています新しく追加された要素ではなく元のリストから要素を評価するだけです。またappendない+=

colours = ["red"] 
new = colours[:] # assign new list/copy to a name. 
for i in colours: 
    if i == "red": 
     new += ["red"] # add to new list 
    if i == "black": 
     new += ["white"] 
print(colours) 

する必要があります:あなたは、新しいリストを作成しようとしている

colours = ["red"] 
new = colours[:] 
for i in colours: 
    if i == "red": 
     new.append("red") 
    if i == "black": 
     new.append("white") 
print(colours) 
関連する問題