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

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

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

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

Q&A

解決済

5回答

1344閲覧

if文・繰り返し処理を使い、リストから要素を取り出し、取り出されたリスト内の残りの個数などを表示させたい場合

dd_

総合スコア111

Python

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

0グッド

0クリップ

投稿2021/10/23 16:45

編集2021/10/24 08:56

やりたい事

リスト内に11個の要素があったとして
繰り返し処理を使い
3個ずつランダムに要素を取り出し
リストに「リストとして」追加し
最後に余った要素の個数を表示させたいです

やったこと、調べた事

まず自分なりにコードを書いてみました。

python

1import random 2 3li1 = list(range(1, 12)) 4li2 = [] 5 6def function(): 7 li2.append(random.sample(li1, 3)) 8 li2.append(random.sample(li1, 3)) 9 li2.append(random.sample(li1, 3)) 10 print(li2) 11 print(str(len(li1)) + "個余りました!") 12 13function() 14# [[1, 10, 4], [10, 3, 2], [11, 6, 1]] 15# 11個余りました!

これでli2での得たい実行結果は得られたのですが
残りの要素の個数を表示させられず。

python 繰り返し
python 繰り返し リスト 取り出す
で調べてみて

コードを書いてみようと思ったのですが
なかなか上手くいかず
なんとなくですが日本語で
骨組みを考えてみました

関数名  もしli1内の個数が3つ以上なら  li1からランダムで3つずつ取り出しli2に追加(ここでグルグル回して)    もしli1内の個数が3未満なら  完成したli2のリストを表示  li1に残った要素の個数の表示

またなんとなくですが
下のようにコードを書いてみました。

python

1import random 2 3li1 = list(range(1, 12)) 4li2 = [] 5def function(): 6 while len(li1) >= 3: 7 li2.append(random.sample(li1, 3)) 8 9 else: 10 print(li2) 11 print(str(len(li1)) + "個余りました!") 12 13function()

これだと、得たい実行結果は得られませんでした。

そもそも、骨組みがあってるか心配だったので
こちらで質問させていただきました。

完全に丸投げ質問なのは重々承知してます、、、
なにかヒントでも教えて頂けると幸いです。
よろしくお願い致します。

ーー追記ーー

皆様ご回答ありがとうございます。
細かく改善するべき点に気が付く事ができました。
皆様のご回答をもとにコーディングしていきたいと思います。
本当にありがとうございます。

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

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

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

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

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

takasima20

2021/10/23 19:47

残る要素数だったら、元の要素数と処理単位の要素数が分かってるなら計算で求められるけど、それがしたいわけじゃないんスね?
dd_

2021/10/24 08:24

ご質問ありがとうございます。 そうなんです。最終的には残る要素数がわかれば大丈夫なのですが 自分としては計算で求めるのではなく、残り要素数をカウントしたいと思っております。
guest

回答5

0

やりたいことが、箱の中に番号付きのクッキーが11個入っていて、それを3個ずつ子供にあげ、足りなくなったら残りの数を知りたい、というのであれば以下の様に考えます。

箱を振ってクッキー一個ずつ取りだして一列に並べておきます。これで順番はランダムになりました。
この列の手前から3個づつ取っていって残りが3個未満になれば、残りを数えれば良いのです。コードにすると以下です。

python

1import random 2 3li1 = list(range(1, 12)) 4li2 = [] 5def function(): 6 global li1 7 li1 = random.sample(li1, len(li1)) 8 while len(li1) >= 3: 9 li2.append(li1[0:3]) 10 li1 = li1[3:] 11 else: 12 print(li2) 13 print(str(len(li1)) + "個余りました!") 14 15function()

投稿2021/10/23 23:38

編集2021/10/23 23:38
ppaul

総合スコア24670

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

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

0

ベストアンサー

関数に分けるのであれば、元のリスト(と取り出す個数)を引数にとり、生成したリストと余りの個数を返すようにすると使い勝手が良くなるかと思います。

Python

1import random 2 3def function( l, n=3): 4 random.shuffle(l) 5 L = len(l) 6 ret = [ l[i:i+n] for i in range(0, L-n+1, n)] # n個ずつ 7 return ret, L % n 8 9li1 = list(range(1, 12)) 10li2, mod = function(li1) 11print(li2) # [[4, 6, 5], [10, 9, 1], [11, 3, 7]] 12print(f'{mod}個余りました。') # 2個余りました。

投稿2021/10/24 01:41

can110

総合スコア38341

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

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

0

random.sample関数は配列からランダムな要素をピックアップしているだけで、元の配列には変更を加えません。
sample関数でピックアップしたものを元の配列から検索して削除するのは二度手間なので、そういう用途であればsample関数ではなく、素直にランダムなインデックスを3つ生成して、そのインデックスの要素を3つの要素の配列として切り出して返す(元の配列からはそれらの要素を削除する)関数を作ればよいのではないでしょうか。

投稿2021/10/23 17:02

175

総合スコア147

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

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

0

質問にあるコードにあるdef function()

Python

1def function(): 2 li2.append(random.sample(li1, 3)) 3 li2.append(random.sample(li1, 3)) 4 li2.append(random.sample(li1, 3)) 5 print(li2)

まではこのままにして、この後、以下のようにするとよいと思います。

  1. リストのリストであるli2 を一次元化したリストli3を作る。(多次元のリストをflatにする、と言ったりします)
  2. 上記で得られた li3 の重複を削除した集合 st3 を作る。
  3. そうすると使った数の個数は、st3 の要素数になるので、li1の要素数からst3の要素数を引けば余った要素の個数が得られる。

以下は上記の考え方による、def function() の修正版です。

Python

1import random 2 3li1 = list(range(1, 12)) 4li2 = [] 5 6def function(): 7 li2.append(random.sample(li1, 3)) 8 li2.append(random.sample(li1, 3)) 9 li2.append(random.sample(li1, 3)) 10 print(li2) 11 12 li3 = sum(li2, []) # li2を flat する。 13 print(li3) 14 st3 = set(li3) # li3から集合を作る(重複がなくなる) 15 print(st3) 16 print(str(len(li1) - len(st3)) + "個余りました!") 17 18function() 19

投稿2021/10/23 17:01

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

2つの方法を書いてみました。

  • 一つずつ pick する手順をそのまま書いたもの
  • pick する回数を計算して、一気に pick するもの

どちらも、
pick したリストはピックした順番のリストになり、
残りのlist は、もとのリストの順番を保って、pick されなかった要素のリスト
になります。
残った要素のリストの順番が保っているのがこの回答でのキモです。
残りリストの順番を保つ必要がない または残りリストは返す必要がない というなら、もっとコードを短くできます、

p.py

python3

1import random 2 3def my_task(lst): 4 lst_picked = [] # 取り出した要素 5 lst_remain = lst[:] # 残った要素 6 7 while True: 8 if len(lst_remain) < 3: 9 break; 10 for _i in range(3): 11 # 一つ pick する 12 p = random.randrange(0, len(lst_remain)) 13 x = lst_remain.pop(p) 14 lst_picked.append(x) 15 # print(lst_picked, lst_remain) 16 return lst_picked, lst_remain 17 18def my_task_x(lst): 19 len_lst = len(lst) 20 len_picked = len_lst // 3 * 3 21 if len_picked == 0: 22 return [[], lst] 23 24 idxs = list(range(0, len_lst)) 25 random.shuffle(idxs) 26 return [ 27 [lst[i] for i in idxs[0:len_picked]], # [ピックした順番の要素 28 [lst[i] for i in range(len_lst) if i in idxs[len_picked:]] # lst の順番を保った残りの要素 29 ] 30 31lst1 = list(range(1, 12)) 32for _i in range(2): 33 lst2, lst3 = my_task(lst1) 34 print(lst2, lst3) 35 print(f'{len(lst3)}個余りました。') 36 37print() 38for _i in range(2): 39 lst2, lst3 = my_task_x(lst1) 40 print(lst2, lst3) 41 print(f'{len(lst3)}個余りました。') 42 43print() 44DATA = [ 45 [1, 2, 3, 1, 2, 3, 1, 2 ,3, 1, 2], 46 [10, 11, 12], 47 [1, 2] 48] 49for d in DATA: 50 print(my_task(d)) 51 print(my_task_x(d)) 52

実行例
イメージ説明

投稿2021/10/24 21:33

katoy

総合スコア22324

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問