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

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

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

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

Q&A

解決済

2回答

3307閲覧

重複のない乱数を10個生成しリストに入れ、それを表示するプログラムで、変な実行結果が出る

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

0クリップ

投稿2019/05/18 21:46

重複のない乱数を10個生成し、それをリストに入れ」表示するプログラムを作っているのですが、実行すると本来は3桁の整数10個表示されるはずが、{<generator object <genexpr> at 0x000002552C1BF780>}と表示されてしまいます。試しに3行目の「for _ in range(10)」を消して実行してみたところ、通常通り整数が出力されたので、おそらくここに問題があるかと思われますが、このエラーの原因は何でしょうか?

↓ プログラム

python

1import random 2L1=set() 3L1.add(random.randint(150,185) for _ in range(10)) 4print(L1) 5

↓ 実行結果

python

1{<generator object <genexpr> at 0x000002552C1BF780>}

↓ 本来出力されるべき実行結果(あくまで一例。値は毎回変わる)

python

1{150,153,155,158,163,160,164,167,172,170}

↓ 3行目の「for _ in range(10)」を消した時の実行結果(あくまで一例。値は毎回変わる)

python

1{165}

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

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

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

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

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

guest

回答2

0

ベストアンサー

まず以下のように(~ for _ in ~)というのは実はgenerator objectになり、以下記載のlist(f)あるいは[f]でリストになります。

Python

1f = (_ for _ in range(3)) 2print(f) # <generator object <genexpr> at 0x~> 3print(list(f)) # [0, 1, 2]

では以下のように書けばよいかというと、これは[0,1,2]という**unhashable(な1要素)**を追加しようとするのでダメです。

Python

1L1=set() 2L1.add(list(f)) # TypeError: unhashable type: 'list'

ではさらに以下のように書けば実行はできますが、乱数のため重複する要素を返す場合があり10要素に満たなくなる場合があります。

Python

1import random 2random.seed(110) # 出現値を固定 3 4# これだと10要素に満たない場合がある! 5L1=set(list(random.randint(150,185) for _ in range(10))) 6print(L1) # {165, 167, 174, 176, 180, 182, 184, 154}

結局、以下のようにあらかじめ150~185の整数を生成してシャッフルし10個選択することで欲しい結果を得ることができます。

Python

1L1 = set( random.sample(range(150,186), 10) ) 2print(L1) # {164, 166, 170, 182, 150, 152, 185, 154, 155, 157}

投稿2019/05/18 22:36

can110

総合スコア38262

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

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

退会済みユーザー

退会済みユーザー

2019/05/18 23:35

ご回答ありがとうございます。解決しました!
guest

0

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

python3

1import random 2 3num_set = {random.randint(150,185) for _ in range(10)} 4print(num_set) 5print(type(num_set)) 6 7num_lst =[random.randint(150,185) for _ in range(10)] 8print(num_lst) 9print(type(num_lst))

実行結果
イメージ説明

参考情報

  • 【Python3】内包表記まとめ

https://qiita.com/kennygt51/items/a89014ab85a068df69c5

追記:
上の実行例でわかるように set に場合は重複が除外されます。したがって、10 個の数値が取得できるとは限りません。
list の場合は 10 個の数値が得られますが、重複は除外されません。

重複しない数値を10個つくりたいなら、こんなふうにしては?

python3

1num_set = set() 2while len(num_set) < 10: 3 num_set.add(random.randint(150,185)) 4print(num_set) 5 6num_set = set(random.sample(range(150, 186), 10)) 7print(num_set)

while をつかっている例では、無限ループになってしまう場合があります。(200個の数値を得ようとした場合など)
sample を使っているでは、 sample(range(150, 186), 200) などとすると例外が発生します。(無限ループにはならない)
randint(150,185) と sample(range(150, 186),...) で 185 と 186 の指定の差にも注意が必要です. (range(150, 185) としていまうと、 185 が結果にふくまれなくなってしまいます。

参考情報

  • Pythonでランダムな小数・整数を生成するrandom, randrange, randintなど

https://note.nkmk.me/python-random-randrange-randint/

ページ中で sample を検索するとよいです。

投稿2019/05/18 22:20

編集2019/05/18 23:58
katoy

総合スコア22324

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

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

退会済みユーザー

退会済みユーザー

2019/05/18 23:35

ご回答ありがとうございます。解決しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問