#問題概要
100枚のカードを1回目は1枚おき、2回目は2枚おき・・・に裏返していって最後に裏返っているカードを求める。
#Code
#Q03カードを裏返せ
cards0 = [-1]*100 #最初。1=表, -1=裏
cards = [-1, 1]*50 #2つ目
step = 3 #何枚おきに裏返すか
#step枚ごとにカードを裏返す。裏返すカードがなくなったら終了
while cards0 != cards:
cards0 = cards[:]
for i in range(step-1, len(cards), step):
cards[i] *= -1
step += 1
#裏返っているカードが何枚目かを表示する
backs = [i+1 for i in range(len(cards)) if cards[i] == -1]
print(backs)
#参考
##配列の生成
list1 = [0] * 3
print(list1) # [0, 0, 0]
list2 = [0, 1] * 3
print(list2) # [0, 1, 0, 1, 0, 1]
参考:https://note.nkmk.me/python-list-initialize/
##配列のコピー
Pythonでは 配列のコピーは参照渡しなので リスト型はミュータブルオブジェクトで、コピーを作ったとき 単純な変数代入ではオブジェクトのコピーを作らずにオブジェクトを共有するため、片方の変数からリスト内容を変更するともう片方の変数のリスト内容も変更される。
※ @shiracamusさんのコメントを元に訂正しました。ありがとうございました。
a = [1, 2, 3]
b = a
b[2] = 4
print(b) #[1, 2, 4]
print(a) #[1, 2, 4]
値渡しをしたいとき 独立したコピーを作りたいときはスライスを使う。
a = [1, 2, 3]
b = a[:]
b[2] = 4
print(b) #[1, 2, 4]
print(a) #[1, 2, 3]
参考:https://qiita.com/hrs1985/items/4e7bba39a35056de4e73
##ミュータブルとイミュータブル
オブジェクトによっては 値 を変更することが可能です。値を変更できるオブジェクトのことを mutable と呼びます。生成後に値を変更できないオブジェクトのことを immutable と呼びます。
ミュータブル:リスト、ディクショナリ、セットなど
イミュータブル:数値、文字列、タプルなど
どういうことかというと、イミュータブルなオブジェクトの値を変更しようとすると、新しいオブジェクトが生成される。ミュータブルなオブジェクトでは既存のオブジェクトの値が変更される。
そのため、変数をコピーした時の挙動が異なる。
a=b=1
print(id(a)) # 140716556333904
a=2
print(id(a)) # 140716556333936 ★新しいオブジェクトが生成される
print(b) #1 ★aの変更はbに影響しない
a=b=['hoge']
print(id(a)) #2667037271944
a[0] = 'fuga'
print(id(a)) #2667037271944 ★既存のオブジェクトが変更される
print(b) #['fuga'] ★aの変更はbに影響する
##リスト内包表記
backs = [i+1 for i in range(len(cards)) if cards[i] == -1]
print(backs)
は以下と同じ
backs=[]
for i in range(len(cards)):
if cards[i] == -1:
backs.append(i+1)
print(backs)