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

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

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

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

Python

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

Q&A

解決済

3回答

996閲覧

Pythonのリスト:その要素の取りうる値が複数の場合のすべての組み合わせに対応するリストの生成方法

yoshikazu.egawa

総合スコア3

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2021/08/06 02:06

編集2021/08/06 05:05

前提・実現したいこと

下記のようなリストを自動的に生成するpythonプログラムを書きたいと思っています。

slist = [a0, a1, a2, a3, a4, - - - , an-1]

各要素aiの取りうる数値
a0 = 0
a1 = -1, 0, 1
a2 = (a1-1), a1, (a1+1)
a3 = (a2-1), a2, (a2+1)


an-1 = (an-2-1), an-2, (an-2+1)

リストの取りうる場合の数は、3**(n-1)個となると思います。
それらを、slist[i] の形で取得したいと思うのですが、どうすればよいでしょうか?

該当のソースコード

試したこと

考えましたが、どうしても思いつきませんでした。

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

python3.7を使っています。

補足情報(取得したいリストの事例)

2要素のリストの場合(n=2)
(3通り)
[0, -1]
[0, 0]
[0, -1]

3要素の場合(n=3)
(9通り)
[0, -1, -2]
[0, -1, -1]
[0, -1, 0]
[0, 0, -1]
[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[0, 1, 2]

4要素の場合(n=4)
(3*(n-1)=27通りになります)
[0, -1, -2, -3]
[0, -1, -2, -2]
[0, -1, -2, -1]
[0, -1, -1, -2]
[0, -1, -1, -1]
[0, -1, -1, 0]
[0, -1, 0, -1]
[0, -1, 0, 0]
[0, -1, 0, 1]
[0, 0, -1, -2]
[0, 0, -1, -1]
[0, 0, -1, 0]
[0, 0, 0, -1]
[0, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 1, 0]
[0, 0, 1, 1]
[0, 0, 1, 2]
[0, 1, 0, -1]
[0, 1, 0, 0]
[0, 1, 0, 1]
[0, 1, 1, 0]
[0, 1, 1, 1]
[0, 1, 1, 2]
[0, 1, 2, 1]
[0, 1, 2, 2]
[0, 1, 2, 3]
以上です

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

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

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

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

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

quickquip

2021/08/06 02:54 編集

具体的な例、例えば元になる列が[3, 7, 10] の時ほしい結果はどうなるのか、とかn=3が4の時の結果などを完全に書くと伝わりやすいと思います。 今のところnの意味が伝わりません…
quickquip

2021/08/06 02:56

slistが入力なのか、欲しいものなのかも読み取れませんでした。
yoshikazu.egawa

2021/08/06 03:44

説明不足で申し訳ありません。slistが欲しいものです。 2要素のリストの場合(n=2) (3通り) [0, -1] [0, 0] [0, -1] 3要素の場合(n=3) (9通り) [0, -1, -2] [0, -1, -1] [0, -1, 0] [0, 0, -1] [0, 0, 0] [0, 0, 1] [0, 1, 0] [0, 1, 1] [0, 1, 2]
yoshikazu.egawa

2021/08/06 03:45

4要素の場合(n=4) (3*(n-1)=27通りになります) [0, -1, -2, -3] [0, -1, -2, -2] [0, -1, -2, -1] [0, -1, -1, -2] [0, -1, -1, -1] [0, -1, -1, 0] [0, -1, 0, -1] [0, -1, 0, 0] [0, -1, 0, 1] [0, 0, -1, -2] [0, 0, -1, -1] [0, 0, -1, 0] [0, 0, 0, -1] [0, 0, 0, 0] [0, 0, 0, 1] [0, 0, 1, 0] [0, 0, 1, 1] [0, 0, 1, 2] [0, 1, 0, -1] [0, 1, 0, 0] [0, 1, 0, 1] [0, 1, 1, 0] [0, 1, 1, 1] [0, 1, 1, 2] [0, 1, 2, 1] [0, 1, 2, 2] [0, 1, 2, 3] 以上です
quickquip

2021/08/06 03:56

情報はこの欄にではなく、質問を編集して記載しましょう。
can110

2021/08/06 04:31

欲しいリストの生成規則が理解できません。 まずリストの数ですが n=0:[0]の1通り n=1:[0]の1通り×(-1,0,1)の3通り=3通り n=2:[0]の1通り×(-1,0,1)の3通り×(-2,-1,0,1,2)の5通り=15通り と考えたのですが、違いますよね? n=2のときなぜ9通りでそれらのリストになるのかが分かりません。
yoshikazu.egawa

2021/08/06 04:55

can110さんのご質問で「各リスト(行)の要素の数は、iの値に関係なく3個ではないでしょうか」にある通り、各要素の数は、その前の要素それぞれに対して3通りです。(生成規則としては、当該要素は、そのひとつ前の要素aに対して、(a-1, a, a+1)の3通りとなります、5通りとはなりません) n=1:[0]の1通り n=2:[0]の1通り×(-1,0,1)の3通り(3**(n-1)=3) n=3:[0]の1通り×[1](-1,0,1)の3通り×([1]の要素それぞれに対して)3通り=9通りになります。(3**(n-1)=9) n=4:[0]の1通り×[1](-1,0,1)の3通り×([1]の要素それぞれに対して)3通り×([2]の要素それぞれに対して)3通り=27通りになります。 (3**(n-1)=27)
yoshikazu.egawa

2021/08/06 05:02

質問を見直したら、「各要素aiの取りうる数値」のところに、誤りがあるのを発見しました。この間違いがご理解いただけなかった理由だと反省しています。申し訳ありませんでした。
can110

2021/08/06 05:14

おそらく理解できました。それをもとに回答を修正しました。
guest

回答3

0

再帰関数を使うとこうです。

python

1def make_slist(n, zlist=None): 2 if zlist == None: 3 zlist = [0] 4 if n == 1: 5 return [zlist] 6 else: 7 plist = zlist.copy() 8 nlist = zlist.copy() 9 plist.append(zlist[-1]+1) 10 nlist.append(zlist[-1]-1) 11 zlist.append(0) 12 return make_slist(n-1, plist)+make_slist(n-1, nlist)+make_slist(n-1, zlist)

実行結果

python

1>>> make_slist(1) 2[[0]] 3>>> make_slist(2) 4[[0, 1], [0, -1], [0, 0]] 5>>> make_slist(3) 6[[0, 1, 2], [0, 1, 0], [0, 1, 0], [0, -1, 0], [0, -1, -2], [0, -1, 0], [0, 0, 1], [0, 0, -1], [0, 0, 0]] 7>>> make_slist(4) 8[[0, 1, 2, 3], [0, 1, 2, 1], [0, 1, 2, 0], [0, 1, 0, 1], [0, 1, 0, -1], [0, 1, 0, 0], [0, 1, 0, 1], [0, 1, 0, -1], [0, 1, 0, 0], [0, -1, 0, 1], [0, -1, 0, -1], [0, -1, 0, 0], [0, -1, -2, -1], [0, -1, -2, -3], [0, -1, -2, 0], [0, -1, 0, 1], [0, -1, 0, -1], [0, -1, 0, 0], [0, 0, 1, 2], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, -1, 0], [0, 0, -1, -2], [0, 0, -1, 0], [0, 0, 0, 1], [0, 0, 0, -1], [0, 0, 0, 0]] 9

投稿2021/08/06 05:24

ppaul

総合スコア24670

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

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

yoshikazu.egawa

2021/08/06 06:15

ご回答をありがとうございました。 初めて質問をさせていただいた初学者ですが、これだけ多様な解があることに驚くとともに、遠い道のりだと感じています。勉強の参考にさせていただいてレベルアップを図っていきたいと思います。
guest

0

ベストアンサー

もしかしたらもっと速い実装あるかもしれませんが…
生成規則をもとに素直に実装していけばよいです。
以下のように累積的に求めていけばよいです。

Python

1n = 3 2ret_list = [[0]] 3for i in range(1,n): 4 new_list = [] 5 for one in ret_list: 6 # ひとつ手前の要素の値に-1,+0,+1した要素を追加 7 new_list.append( one + [one[i-1]-1]) 8 new_list.append( one + [one[i-1]]) 9 new_list.append( one + [one[i-1]+1]) 10 ret_list = new_list 11 12print(*ret_list, sep='\n') 13""" 14n=2 15[0, -1] 16[0, 0] 17[0, 1] 18n=3 19[0, -1, -2] 20[0, -1, -1] 21[0, -1, 0] 22[0, 0, -1] 23[0, 0, 0] 24[0, 0, 1] 25[0, 1, 0] 26[0, 1, 1] 27[0, 1, 2] 28n=4 29[0, -1, -2, -3] 30[0, -1, -2, -2] 31[0, -1, -2, -1] 32[0, -1, -1, -2] 33[0, -1, -1, -1] 34[0, -1, -1, 0] 35[0, -1, 0, -1] 36[0, -1, 0, 0] 37[0, -1, 0, 1] 38[0, 0, -1, -2] 39[0, 0, -1, -1] 40[0, 0, -1, 0] 41[0, 0, 0, -1] 42[0, 0, 0, 0] 43[0, 0, 0, 1] 44[0, 0, 1, 0] 45[0, 0, 1, 1] 46[0, 0, 1, 2] 47[0, 1, 0, -1] 48[0, 1, 0, 0] 49[0, 1, 0, 1] 50[0, 1, 1, 0] 51[0, 1, 1, 1] 52[0, 1, 1, 2] 53[0, 1, 2, 1] 54[0, 1, 2, 2] 55[0, 1, 2, 3] 56"""

以前の回答

iの場合の取りえる数値は-i+iと表せるので以下でよいかと思います。

Python

1n = 5 2slist = [list(range(-i,i+1)) for i in range(n)] 3 4print(*slist, sep='\n') 5""" 6[0] 7[-1, 0, 1] 8[-2, -1, 0, 1, 2] 9[-3, -2, -1, 0, 1, 2, 3] 10[-4, -3, -2, -1, 0, 1, 2, 3, 4] 11"""

投稿2021/08/06 02:29

編集2021/08/06 05:14
can110

総合スコア38341

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

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

yoshikazu.egawa

2021/08/06 02:43

申し訳ありません。説明の仕方が悪かったのかもしれません。 たとえば、以下のような形で欲しいのです。(n=4の場合) [0, -1, -2, -3] [0, -1, -2, -2] [0, -1, -2, -1] [0, -1, -1, -2] [0, -1, -1, -1] [0, -1, -1, 0] [0, -1, 0, -1] [0, -1, 0, 0] [0, -1, 0, 1] [0, 0, -1, -2] [0, 0, -1, -1] [0, 0, -1, 0] [0, 0, 0, -1] [0, 0, 0, 0] [0, 0, 0, 1] (以下続きます)
can110

2021/08/06 02:58

より単純なa2の場合はどうなりますか? 各リスト(行)の要素の数は、iの値に関係なく3個ではないでしょうか?
yoshikazu.egawa

2021/08/06 04:19

その通りです。 質問を修正し、欲しいリストの具体的な事例を追加しました。
yoshikazu.egawa

2021/08/06 06:08

ご回答ありがとうございました。 私のイメージにぴったりだったので、ベストアンサーとさせていただきました。私にとっての初めての質問でしたが、大勢の方から回答をいただけてうれしく思いました。いろいろな解を示していただいて、とても勉強になりました。
guest

0

先頭の0は不要(情報がない)なので取り除いていいです。そうした方が見通しがよくなります。

まず[-1, 0, 1]でn個の直積を作ります。

plain

1>>> from itertools import product 2 3>>> for x in product([-1, 0, 1], repeat=3): 4... print(list(x)) 5[-1, -1, -1] 6[-1, -1, 0] 7[-1, -1, 1] 8[-1, 0, -1] 9[-1, 0, 0] 10[-1, 0, 1] 11[-1, 1, -1] 12[-1, 1, 0] 13[-1, 1, 1] 14[0, -1, -1] 15[0, -1, 0] 16[0, -1, 1] 17[0, 0, -1] 18[0, 0, 0] 19[0, 0, 1] 20[0, 1, -1] 21[0, 1, 0] 22[0, 1, 1] 23[1, -1, -1] 24[1, -1, 0] 25[1, -1, 1] 26[1, 0, -1] 27[1, 0, 0] 28[1, 0, 1] 29[1, 1, -1] 30[1, 1, 0] 31[1, 1, 1]

例えばここから7番目の[-1, 1, -1]を取り出します。この列の第i項までの和を作ります。
第1項 -1
第2項 -1 + 1 = 0
第3項 -1 + 1 -1 = -1
これで[-1, 0, -1] という列ができました。

さて、質問の4要素の場合の7番目を見てください。[0, -1, 0, -1] でした。一致していますね?

質問の数列の構造はこのようになっています。


回答

>>> from itertools import accumulate, product >>> for x in product([-1, 0, 1], repeat=3): ... print(list(accumulate(x))) [-1, -2, -3] [-1, -2, -2] [-1, -2, -1] [-1, -1, -2] [-1, -1, -1] [-1, -1, 0] [-1, 0, -1] [-1, 0, 0] [-1, 0, 1] [0, -1, -2] [0, -1, -1] [0, -1, 0] [0, 0, -1] [0, 0, 0] [0, 0, 1] [0, 1, 0] [0, 1, 1] [0, 1, 2] [1, 0, -1] [1, 0, 0] [1, 0, 1] [1, 1, 0] [1, 1, 1] [1, 1, 2] [1, 2, 1] [1, 2, 2] [1, 2, 3]

投稿2021/08/06 05:09

編集2021/08/06 08:59
quickquip

総合スコア11235

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

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

yoshikazu.egawa

2021/08/06 06:11

ご回答をありがとうございました。とてもシンプルな回答で驚きましたが、このシンプルな計算で、数学的になぜそうなるかについては、私の理解を超えていて今後勉強したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問