🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python

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

Q&A

解決済

8回答

557閲覧

forを多用しない数字グループのラベル付け

iwase13

総合スコア11

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python

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

0グッド

1クリップ

投稿2020/12/07 12:38

グループ分けされた数字にラベル付けをしたい。
for文を多用した上、if文を用いてスマートじゃないので、
斬新なアイデアが有れば、お教え下さい。

数字は0から11の12個で、
無秩序に下記のように3グループに分かれています。
第1ぐ[4,5,9,10]
[0,2,7]
[1,3,6,8,11]

ラベルは
[1, 2, 1, 2, 0, 0, 2, 1, 2, 0, 0, 2]
と出力されます。

import itertools classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] temp_list = list(itertools.chain.from_iterable(classes)) target = list(range(len(temp_list))) index = list(range(len(temp_list))) for i, id_class in enumerate(classes): for k in range(len(id_class)): for j in range(len(index)): if index[j]==id_class[k]: target[j] = i print(target)

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

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

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

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

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

guest

回答8

0

ベストアンサー

python

1import numpy as np 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5arr = np.concatenate(classes) 6lengths = list(map(len, classes)) 7w = np.repeat(np.arange(len(lengths)), lengths) 8 9np.bincount(arr, w) 10# array([1., 2., 1., 2., 0., 0., 2., 1., 2., 0., 0., 2.])

投稿2020/12/08 04:16

kirara0048

総合スコア1399

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

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

iwase13

2020/12/10 05:02

Forを1度も使わず、numpyで処理されるとは! 勉強になります。 有難うございます!!!
guest

0

3つ目のforループは不要ではないでしょうか。

python

1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3target = [-1] * 12 4# target = [-1] * (max(itertools.chain.from_iterable(classes)) + 1) 5 6for i, id_class in enumerate(classes): 7 for j in id_class: 8 target[j] = i

また、numpyを使っていいなら、forループはひとつで書けます。

python

1import numpy as np 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5target_arr = np.empty(12, dtype=int) 6for i, id_class in enumerate(classes): 7 target_arr[id_class] = i 8target = target_arr.tolist()

投稿2020/12/07 23:15

編集2020/12/08 00:32
bsdfan

総合スコア4794

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

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

iwase13

2020/12/10 05:33

ifも使わず、forも1度だけに。 ありがとうございます。 forを使うとrangeを用い、回数を繰り返す事を多用してしまいます。 ネスト内の数字をそのまま代入できますね。 平易な添削で大変勉強になりました。 有難うございます!
guest

0

val -> label の dict をつくり、range(12) に対して、この dict を map するという方針で書いてみました。

python3

1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3labels = [[idx] * len(classes[idx]) for idx in range(len(classes))] 4val_label_hash = dict(zip(sum(classes, []), sum(labels, []))) 5print(list(map(lambda x: val_label_hash[x], range(len(val_label_hash))))) 6 7print() 8print("classes=", classes) 9print(" labels=", labels) 10print("val_label_hash=", val_label_hash)

実行結果
イメージ説明

参考情報

  • Pythonでflatten(多次元リストを一次元に平坦化)

https://note.nkmk.me/python-list-flatten/

投稿2020/12/07 21:38

katoy

総合スコア22324

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

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

iwase13

2020/12/10 05:15 編集

mapとlambdaを使うのですね。 知りませんでした。勉強になります。 有難うございます!
guest

0

あまり使われない collections.ChainMap を使ってみました。

python

1from collections import ChainMap 2 3classes = [[4,5,9,10], [0,2,7], [1,3,6,8,11]] 4c = ChainMap(*map(lambda x: dict.fromkeys(x[1], x[0]), enumerate(classes))) 5ans = list(map(lambda i: c[i], range(12))) 6print(ans)

再帰を使った別案です。

python

1def solve(n, row=0): 2 return row if n in classes[row] else solve(n, row+1) 3 4classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 5ans = list(map(solve, range(12))) 6print(ans) 7

投稿2020/12/07 14:02

編集2020/12/08 03:36
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

iwase13

2020/12/10 04:59

別案の提示まで有難うございます! mapという関数を使えばforの代わりになりますね!
guest

0

for を使わなければいいんですよね。

Python

1import itertools 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5target = list(itertools.chain.from_iterable(classes)) 6def g(i, a): 7 if a: 8 target[a[0]] = i 9 g(i, a[1:]) 10def f(i, a): 11 if a: 12 g(i, a[0]) 13 f(i+1, a[1:]) 14f(0, classes) 15 16print(target)

追記
import itertools なしで、全部自前でやるとすれば、

Python

1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3def h(a, i): 4 return len(a[0]) + h(a[1:], i+1) if a else 0 5target = [0] * h(classes, 0) 6def g(a, i): 7 if a: target[a[0]] = i; g(a[1:], i) 8def f(a, i): 9 if a: g(a[0], i); f(a[1:], i+1) 10f(classes, 0) 11 12print(target)

追記2
a[1:] で新しいリストを作るのは無駄なので、

Python

1classes = [[4, 5, 9, 10], [0, 2, 7], [1, 3, 6, 8, 11]] 2 3def h(i): 4 return len(classes[i-1]) + h(i-1) if i > 0 else 0 5target = [0] * h(len(classes)) 6def g(a, j, i): 7 if j > 0: target[a[j-1]] = i; g(a, j-1, i) 8def f(i): 9 if i > 0: i -= 1; g(classes[i], len(classes[i]), i); f(i) 10f(len(classes)) 11 12print(target)

投稿2020/12/08 01:50

編集2020/12/08 04:54
kazuma-s

総合スコア8224

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

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

iwase13

2020/12/10 05:01

追記も有難うございます。 理解が追い付いてませんが勉強させて頂きます。
guest

0

Python

1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3print([z[1] for z in sorted(sum([[(x,y) for x in w] for w, y in zip(classes,range(len(classes)))],[]))])

と、書いてみた物の、forが3回出てきます。

投稿2020/12/07 13:28

otn

総合スコア85886

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

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

otn

2020/12/07 14:07

やはり、for ないし map が3回は必要そうです。
iwase13

2020/12/10 04:57

高速化の為にはリストの内包表記が必要ですよね。しかし、書きなれていません(汗)
otn

2020/12/10 05:05

いや、高速化とは限らない(あまりならない)と思いますよ。 概ね、内包表記とmapは出来ることが似ています。このfor3回をmap3回に書き直すことも容易です。
iwase13

2020/12/10 05:34

有難うございます。
guest

0

やってみました。

python

1def check(n, classes): 2 for idx, lst in enumerate(classes): 3 if n in lst: 4 return idx 5 6classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 7target = list(range(11)) 8 9[check(i, classes) for i in target]

もうちょっと、よくできるかなぁ。

投稿2020/12/07 13:11

TakaiY

総合スコア13758

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

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

iwase13

2020/12/10 04:57

有難うございます!
guest

0

中間リストを作ると楽だと思います。
このコードが簡潔だと感じるかどうかは慣れ次第ですが。

Python

1import operator as op 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5it = [ 6 (clazz, e) 7 for clazz, es in enumerate(classes) 8 for e in es 9] 10print(f'{it=}') 11 12dst = [ 13 e for e, _ in sorted(it, key=op.itemgetter(1)) 14] 15print(f'{dst=}')

実行結果 Wandbox

it=[(0, 4), (0, 5), (0, 9), (0, 10), (1, 0), (1, 2), (1, 7), (2, 1), (2, 3), (2, 6), (2, 8), (2, 11)] dst=[1, 2, 1, 2, 0, 0, 2, 1, 2, 0, 0, 2]

投稿2020/12/07 12:53

編集2020/12/07 12:56
LouiS0616

総合スコア35668

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

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

iwase13

2020/12/10 04:58

有難うございます。 コードを移植したのですがエラーで動きませんでした。 File "<fstring>", line 1 (it=) ^ SyntaxError: invalid syntax
LouiS0616

2020/12/10 22:47

バージョンの問題ですね。=を外せば動きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問