質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1703閲覧

pythonで、配列aと配列bが交互に出てくるような配列を作りたい。

sk_zappa

総合スコア5

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/06/22 17:34

編集2021/06/22 17:54

イタリックテキスト### 前提・実現したいこと

プログラミング初学者です。pythonの勉強をしています。

整数nを入力し、以下のような交互の羅列を作りたいと考えています。
(例:n=3の時)
[[0, 0.5, 0],
[0.5, 1, 0.5],
[0, 0.5, 0]]
(例:n=4の時)
[[0, 0.5, 0, 0.5],
[0.5, 1, 0.5, 1],
[0, 0.5, 0, 0.5],
[0.5, 1, 0.5, 1]]

つまり、[0と0.5が交互にn回出てくる配列]と、[0.5と1が交互にn回出てくる配列]が、それぞれn回繰り返される配列、を作りたいです。

以下の私の記述では、何が問題となっているのか教えていただけますでしょうか。

発生している問題・エラーメッセージ

python

1def ex5_4(x): 2 test = [0] * x 3 for i in range(0, x): 4 if i % 2 == 0: 5 test[i] = 0 6 else: 7 test[i] = 0.5

などとすることで[0と0.5が交互にn回出てくる配列]もしくは[0.5と1が交互にn回出てくる配列]は作れたのだが、
それらが繰り返し出てくる配列を作れない。

該当のソースコード

python

1def ex5_4(x): 2 test = [0] * x 3 for i in range(0, x): 4 if i % 2 == 0: 5 test[i] = 0 6 else: 7 test[i] = 0.5 8 test = [test] * x 9 for j in range(0, x): 10 if j % 2 != 0: 11 for k in range(0, x): 12 if k % 2 == 0: 13 test[j][k] = 0.5 14 else: 15 test[j][k] = 1 16 return test

試したこと

この状態では

ex5_4(4)

[[0.5, 1, 0.5, 1], [0.5, 1, 0.5, 1], [0.5, 1, 0.5, 1], [0.5, 1, 0.5, 1]]
という結果がかえって来てしまいます。

jに問題があるのかと考え、

python

1def ex5_4(x): 2 test = [0] * x 3 for i in range(0, x): 4 if i % 2 == 0: 5 test[i] = 0 6 else: 7 test[i] = 0.5 8 test = [test] * x 9 for j in range(0, x): 10 if j % 2 != 0: 11 for k in range(0, x): 12 if k % 2 == 0: 13 test[0][k] = 0.5 14 else: 15 test[0][k] = 1 16 return test

以上のようにjが関わってこない記述に改めたのですが、これでも

ex5_4(4)

[[0.5, 1, 0.5, 1], [0.5, 1, 0.5, 1], [0.5, 1, 0.5, 1], [0.5, 1, 0.5, 1]]

と、なぜか全ての配列が変わってしまいます。

補足情報(FW/ツールのバージョンなど)

anaconda3のidleというものを使っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

以下の私の記述では、何が問題となっているのか教えていただけますでしょうか。

test = [test] * x が問題点で、リストの参照を作っています。

Python プログラミング FAQ 多次元のリストを作るにはどうしますか?

このようにして多次元の配列を作ろうとしてしまったことがあるでしょう:

python

1>>> 2>>> A = [[None] * 2] * 3

これを表示したときには問題なさそうに見えます:
しかし値を代入すると、その値が複数の場所に現れてしまいます:

python

1>>> A[0][0] = 5 2>>> A 3[[5, None], [5, None], [5, None]]

これは、* を使ったリストの複製がコピーを作らず、存在するオブジェクトへの参照を作るだけだからです。この *3 は長さ 2 の同じリストへの参照を含むリストを作ります。一つの列に対する変更はすべての列に現れますが、これが望んだ結果であることはまずないでしょう。

解決策: 参照ではなくコピーを作る

test = [test[:] for _ in range(x)]
または
test = [test.copy() for _ in range(x)]


パズル的な内容ですが、おまけで
題材のプログラムはイテレータを使い、以下のように表現できます。

python

1 2from itertools import cycle, islice 3 4def func(n): 5 # 追記: itertools.cycleを使わず 6 # f = lambda xs: [xs[:] for _ in range(n//len(xs)+1)][:n] 7 8 f = lambda xs: list(islice(cycle(xs), 0, n)) 9 a = f([0.0, 0.5]) 10 b = f([0.5, 1.0]) 11 return f([a, b]) 12 13from pprint import pp 14pp(func(3)) 15pp(func(4)) 16pp(func(5)) 17

# cycle('ABCD') --> A B C D A B C D A B C D .

投稿2021/06/22 20:33

編集2021/06/23 06:22
teamikl

総合スコア8760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sk_zappa

2021/06/23 05:49

丁寧にご説明いただき誠にありがとうございます。 参照点について、勉強はしていたのですが、実践でつまずいたときに気づけませんでした。 頂いたご指摘に沿って明示的にコピーを作成したところ、無事に目的のプログラムが書けました。
guest

0

これでどうでしょう。

python

1n=3 2a=[0,0.5,0] 3b=[0.5,1,0.5] 4 5arr = [a if i % 2 == 0 else b for i in range(n)] 6print(arr)

投稿2021/06/22 17:44

TaroToyotomi

総合スコア1449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sk_zappa

2021/06/22 17:58

早速ありがとうございます! ちなみになのですが、私の記述では、jが奇数の場合に、test[j]の中の配列に変更を加えようとしているのですが、どうしてtest[j]のjが偶数の場合も配列が変わってしまったのでしょうか?
lehshell

2021/06/22 22:48

arr[0][0]=2 とすると arr[2][0] も 2 になってしまうコードですが 質問者さんの意図する内容かが気になります。 意図がはっきりわからないため arr = [a[:] if i % 2 == 0 else b[:] for i in range(n)] とするのが無難でしょう。
sk_zappa

2021/06/23 05:51 編集

私の言葉が足りないにも関わらず、代案をご提示頂きましてありがとうございます。 ご提示頂きましたプログラムでも目的のものが作成できました。 代案として頂きましたプログラムの内容はまだ十分に理解出来ていないのですが、これから勉強を進めて理解したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問