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

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

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

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

Q&A

解決済

7回答

940閲覧

多次元リストでリストとリストの間に数字をいれていきたい場合

dd_

総合スコア111

Python

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

0グッド

0クリップ

投稿2021/12/17 17:26

編集2021/12/18 06:22

python

1lis = [[5,6], 2[9,11], 3[15,16], 4[19,22]]

このリストがあり
下の様なリストにするためにコードを書いたのですが
他に良い方法があればお聞きしたいです。

[0, 1, 2, 3, 4, [5, 6], 7, 8, [9, 10, 11], 12, 13, 14, [15, 16], 17, 18, [19, 20, 21, 22]]

やったこと

python

1lis = [[5,6], 2[9,11], 3[15,16], 4[19,22]] 5 6lis2 = [] 7for n in range(len(lis)): 8 l = [] 9 for i in range(lis[n][0], lis[n][-1] + 1): 10 l.append(i) 11 lis2.append(l) 12 13lis3 = [] 14for li in lis2: 15 for l in li: 16 lis3.append(l) 17 18 19new_lis = [] 20n = 0 21for i in range(0, lis2[-1][-1] + 1): 22 if i not in lis3: 23 new_lis.append(i) 24 25n = 0 26for i in range(len(lis2)): 27 ind = new_lis.index(lis2[n][0]-1) 28 new_lis.insert(ind +1, lis2[i]) 29 n += 1 30

このように書いてみました。
結果は以下になります。

[0, 1, 2, 3, 4, [5, 6], 7, 8, [9, 10, 11], 12, 13, 14, [15, 16], 17, 18, [19, 20, 21, 22]]

得たい実行結果は得られたのですが
やってて無理矢理感を感じ
もし他に良い方法があればお聞きしたいと思い
こちらで質問させていただきました。

有識者様のお力をお借りできればと思います。
是非宜しくお願い致します。

追記 2021/12/18 15:17

皆様いつもお世話になっております。
たくさんのご回答ありがとうございます。
私なりにベストアンサーを決めさせていただきました!
しかし皆様のご回答、どれも参考になりました。
そして初歩的ですが新しい発見もありました。ありがとうございます。
日々精進してまいります。

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

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

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

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

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

guest

回答7

0

たとえば、こんなのでどうでしょう?

python3

1lis = [ 2 [5,6], 3 [9,11], 4 [15,16], 5 [19,22] 6] 7 8 9lis2 = [] 10start = 0 11for span in lis: 12 lis2.extend([ 13 *(x for x in range(start, span[0])), 14 [y for y in range(span[0], span[1] + 1)] 15 ]) 16 start = span[1] + 1 17 18 19print(lis2) 20

出力結果:

[0, 1, 2, 3, 4, [5, 6], 7, 8, [9, 10, 11], 12, 13, 14, [15, 16], 17, 18, [19, 20, 21, 22]]

???? replit.com/@kilesa/tera:Q374380

追記

もうひとつ出来ました。こちらははじめに0から22までを含む一次元のリストとしてlis2を作っておいて、lis の含む長さ2のリストが表す区間を子リストで置き換えていきます。

python3

1lis = [ 2 [5,6], 3 [9,11], 4 [15,16], 5 [19,22] 6] 7 8lis2 = [x for x in range(lis[-1][1] + 1)] 9 10d = 0 11for s, e in lis: 12 start = s - d 13 end = e + 1 - d 14 lis2[start:end] = [lis2[start:end]] 15 d += (e - s) 16 17print(lis2) 18

出力結果:

[0, 1, 2, 3, 4, [5, 6], 7, 8, [9, 10, 11], 12, 13, 14, [15, 16], 17, 18, [19, 20, 21, 22]]

???? replit.com/@kilesa/tera:Q374380 #2

追記2

もう一案です。
空リストのlis2に0以上22以下の整数を追加していきますが、その数が lisの要素の閉区間に含まれていれば入れ子のリストに追加し、含まれていなければ lis2 に追加されるように if, elifおよび else を組み立てています。

python3

1lis = [ 2 [5,6], 3 [9,11], 4 [15,16], 5 [19,22] 6] 7 8lis2 = [] 9i = 0 10 11for x in range(lis[-1][1]+1): 12 if i < len(lis) and x == lis[i][0]: 13 lis2.append([x]) 14 elif len(lis2) > 0 and type(lis2[-1]) == list: 15 if x <= lis[i][1]: 16 lis2[-1].append(x) 17 else: 18 lis2.append(x) 19 i += 1 20 else: 21 lis2.append(x) 22 23 24print(lis2) 25 26

出力結果:

[0, 1, 2, 3, 4, [5, 6], 7, 8, [9, 10, 11], 12, 13, 14, [15, 16], 17, 18, [19, 20, 21, 22]]

???? replit.com/@kilesa/tera:Q374380 #3

追記3

一つ目のコード案について、冗長な部分がありました。以下修正点です。

diff

1for span in lis: 2 lis2.extend([ 3- *(x for x in range(start, span[0])), 4+ *range(start, span[0]), 5- [y for y in range(span[0], span[1] + 1)] 6+ [*range(span[0], span[1] + 1)] 7 ]) 8 start = span[1] + 1

???? replit.com/@kilesa/tera:Q374380 #4

追記4

読みやすさの点ではどうかと思いますが追記3のコードを reduce を使って一行に詰めてみたものです。

python3

1from functools import reduce 2 3lis2, _ = reduce(lambda a, s: ([*a[0], *range(a[1], s[0]), [*range(s[0], s[1]+1)]], s[1]+1), lis, ([], 0))

???? replit.com/@kilesa/tera:Q374380 #5

投稿2021/12/17 18:06

編集2021/12/18 05:34
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

dd_

2021/12/17 18:24

kilesa様、お世話になっております! 早速のご回答ありがとうございます。 頂いたご回答の内容は、また日中に詳しく確認させて頂ければと思います!
dd_

2021/12/21 13:27

追記してくださってた事、今気が付きました。。 大変失礼いたしました。。 kilesa様、もし見てくださってたら謝罪させて頂きたいです。 本当に失礼な事をしてしまい申し訳ありませんでした。。 追記の内容しっかりと拝見させて頂きます!! ありがとうございます。
guest

0

1行で生成すると

Python

1lis = [[5,6], [9,11], [15,16], [19,22]] 2ans = sum((n:=0)or[[*range(i, top)]+[[*range(top, n:=end+1)]] for top,end in lis if (i:=n)>=0], []) 3print(ans)

投稿2021/12/18 02:21

lehshell

総合スコア1147

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

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

dd_

2021/12/18 06:26

ご回答ありがとうございます! とても参考になりました。 日々精進してまいります。
guest

0

python

1lis = [ 2 [5,6], 3 [9,11], 4 [15,16], 5 [19,22] 6] 7 8a = [] 9i = 0 10for s, e in lis: 11 a += [*list(range(i, s)), list(range(s, i := e+1))] 12 13print(a)

追記
lehshellさんの回答を見て、私も 1行にしてみました。

python

1a = sum((i:=0) or [[*range(i, s), [*range(s, i:=e+1)]] for s, e in lis], [])

投稿2021/12/18 01:35

編集2021/12/18 03:15
kazuma-s

総合スコア8224

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

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

dd_

2021/12/18 06:26

ご回答ありがとうございます! 参考にさせて頂きます!! ありがとうございます。
guest

0

ベストアンサー

こんな方法はどうでしょう。

Python

1dst = [] 2i = 0 3for start, end in lis: 4 dst.extend([e for e in range(i, start)]) 5 dst.append([e for e in range(start, end+1)]) 6 i = end+1 7 8print(dst)

投稿2021/12/18 00:11

LouiS0616

総合スコア35660

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

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

dd_

2021/12/18 06:28

ご回答ありがとうございます! 参考にさせて頂きました。 是非またご機会があれば何卒宜しくお願い致します。 ありがとうございます!
guest

0

考え方はいいと思います。
自分的に率直に書くとこんなかんじでしょか。

python

1lis = [[5,6], 2[9,11], 3[15,16], 4[19,22]] 5 6new_lis = [] 7ci = 0 8for li in lis: 9 for j in range(ci,li[0]): 10 new_lis.append(j) 11 new_lis.append([i for i in range(li[0], li[-1] + 1)]) 12 ci = li[-1] + 1 13print(new_lis)

投稿2021/12/17 21:24

takasima20

総合スコア7458

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

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

dd_

2021/12/18 06:30

ご回答ありがとうございます! for 文の組み方とても参考になりました。 ありがとうございました!
guest

0

python

1lis = [[5, 6], [9, 11], [15, 16], [19 ,22]] 2 3lst = lis + [lis[-1]] 4new_lis = sum([ 5 [[*range(x1, x2+1)]] + [*range(x2+1, y1)] 6 for (x1, x2), (y1, y2) in zip(lst, lst[1:]) 7 ], []) 8new_lis[:0] = [*range(0, new_lis[0][0])] 9print(new_lis) 10 11# 12[0, 1, 2, 3, 4, [5, 6], 7, 8, [9, 10, 11], 12, 13, 14, [15, 16], 17, 18, [19, 20, 21, 22]]

投稿2021/12/17 18:20

melian

総合スコア19714

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

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

dd_

2021/12/17 18:26

melian様、ご回答ありがとうございます!お世話になっております。 頂いたご回答は、また日中に詳しく確認させて頂ければと思います!
guest

0

次のコードを研究してみてください。

p.py

python3

1lis = [ 2 [5, 6], 3 [9, 11], 4 [15, 16], 5 [19, 22] 6] 7 8# 段階的に処理してみる 9lis2 = list(map( lambda x: list(range(x[0], x[1] + 1)), lis)) 10lis3 = sum(lis2, []) 11print("lis の要素を展開する") 12print(" lis3 = ", lis3) 13 14lis4 = [[x] for x in range(0, lis3[-1]) if x not in lis3] 15print("lis に含まれていない要素を列挙する") 16print(" lis4 = ", lis4) 17 18print("lis を 展開する") 19lis_ex = list(map(lambda x: list([e for e in range(x[0], x[1] + 1)]), lis)) 20print("lis_ex", lis_ex) 21 22lis5 = sorted(lis4 + lis_ex) 23print("両者を結合してソートする") 24print(" lis5 = ", lis5) 25 26print("サイズ 1 の要素は list から int に変換する") 27lis6 = list(map(lambda x: x[0] if len(x) == 1 else x, lis5)) 28print(" lis6 = ", lis6) 29 30# 上の処理を1 行にまとめる 31result = list( 32 map(lambda x: x[0] if len(x) == 1 else x, 33 sorted(list(map(lambda y1: list([e for e in range(y1[0], y1[1] + 1)]), lis)) 34 + [[y] for y in range(0, lis[-1][1]) 35 if y not in sum(list(map( lambda z: list(range(z[0], z[1] + 1)), lis)), [])]) 36 ) 37) 38print(result)

実行例
イメージ説明

処理をまとめるときには、事前に作業変数を宣言せずに、lis だけを使って書くのが好ましいです。(個人的な嗜好)

投稿2021/12/19 05:31

編集2021/12/19 05:51
katoy

総合スコア22324

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

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

dd_

2021/12/19 08:50

ご回答ありがとうございます! 拝見させていただきました。 sorted()などを使うやり方とても参考になりました! 「処理をまとめる」もとても勉強になりました。 今までは処理した結果に 次の処理の結果を足していくという感じで書いていて 作業変数を宣言しすぎて、 見づらく訳が分からなくなる時があったので 各処理を関数化させるようなイメージ?で合ってるか分かりませんが 「処理をまとめる」という事を意識しなければと思いました。 ありがとうございます!
katoy

2021/12/19 20:52

無理に一行にまとめる必要はないです。 メソッドとして定義して、その中でローカル変数を利用して逐次処理しながら結果を汲み上げていけば十分と思います。 上の回答は、計算量やメモリー使用量を意識していません。 動作が遅い、メモリー使用量が多いという問題が出てきたら、その点を踏まえて処理方法を工夫していくと良いです。
dd_

2021/12/20 13:42 編集

遅くなりました。すみません! 本当に勉強になります。。(レベル低すぎてすみません) ちょっとずつ無駄を減らして、扱いやすいコードを書けるように心がけていきたいのと プラスで まだまだ私の扱う計算量は皆様の足元にも及びませんが katoy様のおっしゃる、処理させるデータが多い場合どうしたらいいか、を意識しながらやっていきたいと思います! ご丁寧にご返信くださり、本当に本当にありがとうございますm(_ _)m
katoy

2021/12/21 00:25

計算量、メモリー使用量についてはソートのいろいろなアルゴリズム、実装を研究すると良いです。 (ソートは、プログラミングの教科書でよく扱われている題材です)
dd_

2021/12/21 13:16

ググると、ソートアルゴリズムのそれぞれの計算量、計算時間、メモリー使用量などついてのサイトが出てきました。読んで自分でも試して研究してみたいと思います! ありがとうございますm(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問