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

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

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

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

Python

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

Q&A

解決済

2回答

1164閲覧

for文でのnp.allの使い方

hirochem

総合スコア4

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2021/04/24 13:51

編集2021/04/24 13:58

Python (競技プログラミング) を勉強し始めて数か月(主に仕事後)しか経っていないため不適切な質問や非効率なコードが表示されているかもしれませんが、ご容赦ください。
完全に独学なため、常識的なことでも教えていただけると助かります。
こんな書き方がある、でも示していただけると嬉しいです。

以下に前提条件や試したことを書きます。

入力として
stockには、2種類の商品の在庫数
actには、stockに対する作業の種類 (subは在庫から商品を減らし、addは商品を増やす)
changeには、それぞれの作業におけるstockの変化量を示しており、それぞれリストに入っています。

出力として
在庫が減らす分、存在する場合は在庫数をカンマ区切りで出力し
どちらかの商品の在庫が足りない場合は"Not enough"を出力するとします。
("sub"の数だけ出力がある)

パターン1と2の場合は問題なく動きますが、np.allを用いたパターン3の場合は在庫数が負でも出力されます。

どうしてそうなるのかわからず、解決法を教えていただければ幸いです。

該当のソースコード

パターン1

html

1import numpy as np 2stock = [3,2] 3act = ["sub", "sub", "add", "sub", "sub"] 4change = [[1,2], [3,0], [3, 2], [2,1], [2,2]] 5ans = [] 6for a, b in zip(act, change): 7 tes = [] 8 for h, b2 in zip(stock, b): 9 tes.append(h-b2) 10 if a == "sub": 11 if all((x>=0 for x in tes)): 12 for e, (p, b2) in enumerate(zip(stock, b)): 13 stock[e] -= b2 #stockの個数を変更 14 ans.append(",".join([str(a) for a in stock])) 15 else: 16 ans.append("Not enough") 17 elif a =="add": 18 for e, (p,b2) in enumerate(zip(stock, b)): 19 stock[e] += b2 20for a in ans: 21 print(a)

出力
2,0
Not enough
3,1
Not enough

パターン2

html

1import numpy as np 2stock = [3,2] 3act = ["sub", "sub", "add", "sub", "sub"] 4change = [[1,2], [3,0], [3, 2], [2,1], [2,2]] 5ans = [] 6for a, b in zip(act, change): 7 tes = (np.array(stock)-np.array(b)).tolist() 8 if a == "sub": 9 if all((x>=0 for x in tes)): 10 for e, (p, b2) in enumerate(zip(stock, b)): 11 stock[e] -= b2 #stockの個数を変更 12 ans.append(",".join([str(a) for a in stock])) 13 else: 14 ans.append("Not enough") 15 elif a =="add": 16 for e, (p,b2) in enumerate(zip(stock, b)): 17 stock[e] += b2 18for a in ans: 19 print(a)'

出力
2,0
Not enough
3,1
Not enough

パターン3

html

1import numpy as np 2stock = [3,2] 3act = ["sub", "sub", "add", "sub", "sub"] 4change = [[1,2], [3,0], [3, 2], [2,1], [2,2]] 5ans = [] 6for a, b in zip(act, change): 7 tes = np.array(stock)-np.array(b) 8 if a == "sub": 9 if np.all(x>=0 for x in tes): #これが上手く動作していない? 10 for e, (p, b2) in enumerate(zip(stock, b)): 11 stock[e] -= b2 #stockの個数を変更 12 ans.append(",".join([str(a) for a in stock])) 13 else: 14 ans.append("Not enough") 15 elif a =="add": 16 for e, (p,b2) in enumerate(zip(stock, b)): 17 stock[e] += b2 18for a in ans: 19 print(a)'

出力
2,0
-1,0
0,1
-2,-1

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

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

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

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

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

y_waiwai

2021/04/24 14:21

デバッグぐらいしませんか
hirochem

2021/04/25 13:17

アドバイスありがとうございます! 質問するときもデバックを入れたままの方がいいことを初めて知りました。次からはそうします。ありがとうございます!
guest

回答2

0

ベストアンサー

tesがnumpyのndarrayなので、

python

1if np.all(tes >= 0):

にすればよいです。tes >= 0がbooleanのndarrayになります。

パターン3は numpy.all(ジェネレータ) の書き方になっていますが、numpy.all()はジェネレータの中身を見ずに、ジェネレータそのもの(ジェネレータオブジェクト)として評価するようです。ジェネレータオブジェクトはFalseとして評価される値ではないので、numpy.all(ジェネレータ) は常にTrueを返すことになります。

投稿2021/04/24 15:10

bsdfan

総合スコア4794

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

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

bsdfan

2021/04/24 15:11

あと、回答とは関係ないですが、パターン3で、numpyを使うなら、forを使わずに加減算するとか、もう少し工夫できると思います。
hirochem

2021/04/25 13:18 編集

返信いただきありがとうございます。 回答だけでなく、どうしてパターン3が上手くいかなかったか、まで解説していただいて非常に助かります。 そして、工夫のヒントをいただいたので実際にやってみたところ stock = (np.array(stock) - np.array(b)).tolist() をfor文のところと入れ替えることで上手くいきました! numpyでリストの値を変化させてからリストに戻す、ということが身に付きました。ありがとうございます。
guest

0

np.all(x>=0 for x in tes)np.all([x>=0 for x in tes])に修正しました。

Python

1import numpy as np 2stock = [3,2] 3act = ["sub", "sub", "add", "sub", "sub"] 4change = [[1,2], [3,0], [3, 2], [2,1], [2,2]] 5ans = [] 6for a, b in zip(act, change): 7 tes = np.array(stock)-np.array(b) 8 if a == "sub": 9 if np.all([x>=0 for x in tes]): 10 for e, (p, b2) in enumerate(zip(stock, b)): 11 stock[e] -= b2 #stockの個数を変更 12 ans.append(",".join([str(a) for a in stock])) 13 else: 14 ans.append("Not enough") 15 elif a =="add": 16 for e, (p,b2) in enumerate(zip(stock, b)): 17 stock[e] += b2 18for a in ans: 19 print(a)

投稿2021/04/24 14:12

meg_

総合スコア10760

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

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

hirochem

2021/04/25 13:05

ありがとうございます! 綺麗に動きました! 自分ではなかなか気づけないところだと思うので非常に助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問