teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

追記に関して

2018/04/12 07:49

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -85,4 +85,56 @@
85
85
  [2, 1][count_diff] if count_diff <= 1 else 0))(
86
86
  sum([1 for c1, c2 in zip(true_ans, exam_ans) if c1 != c2])))
87
87
  ```
88
- ご覧の通り可読性は悪いのですが、できなくはありません。
88
+ ご覧の通り可読性は悪いのですが、できなくはありません。
89
+
90
+ ### 質問の追記に関して
91
+ 恐らくzipや内包表記が入り乱れているのでわかりづらいのだと思います。
92
+ ナイーブに書くとこうなります。
93
+
94
+ ```python
95
+ def count_diff(true_ans, exam_ans):
96
+ """同じ文字列長を仮定
97
+ """
98
+ diff_count = 0
99
+ for i in range(len(true_ans)):
100
+ if true_ans[i] != exam_ans[i]:
101
+ diff_count += 1
102
+ return diff_count
103
+ ```
104
+
105
+ これはたぶん追っていけばわかるはずです。
106
+ ついでにzipの出力も確認しておくことにしましょう。
107
+
108
+
109
+ ```python
110
+ >>> list(zip("head", "hhhh"))
111
+ [('h', 'h'), ('e', 'h'), ('a', 'h'), ('d', 'h')]
112
+ ```
113
+
114
+ あとはリスト内包表記にするだけで、これは簡単です。
115
+ ```python
116
+ sum([1 for c1, c2 in zip(right_answer, answer) if c1 != c2])
117
+ ```
118
+
119
+ ただしLouiS0616さんのこのコードは、
120
+
121
+ ```python
122
+ diff = sum(
123
+ 1 for ra, a in zip(right_answer, answer) if ra != a
124
+ )
125
+ ```
126
+
127
+ 0. リスト内包表記ではなくジェネレータ式を使っている
128
+ 1. ジェネレータ式を関数の引数として書く場合、かっこを省略できるという糖衣構文を使っている
129
+
130
+ ので一見すると理解しがたいものに見えます。
131
+
132
+ 1については、ジェネレータ式はジェネレータを作るものです。ジェネレータとはなにかというと、だいたい次のようなポジションだと思ってください。
133
+
134
+ - イテレータ:forで繰り返し処理できるもの。文字列、リスト、タプル、"ジェネレータ"など
135
+ - ジェネレータ:動的に要素が生成されるイテレータ
136
+
137
+ 2については、本来ジェネレータ式は()で囲うことで作ることができるのですが、関数の唯一の引数として渡された場合はこの()を省略できるというルールがあります。それを使われています。
138
+
139
+ 参考:
140
+ [ジェネレータ式の文法について調べてみた ](http://www.rhoboro.com/2017/07/08/python-generator-grammer.html)

3

誤字修正

2018/04/12 07:49

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -71,7 +71,7 @@
71
71
  main()
72
72
  ```
73
73
 
74
- すっきりしたといえばすっきりしましたが、コード行数は大して減ってはいないという見方もできるでしょう。だけれ、これ以上複雑なことをやるとかえって見通しが悪くなるので、これくらいで良いのです。
74
+ すっきりしたといえばすっきりしましたが、コード行数は大して減ってはいないという見方もできるでしょう。だけれ、これ以上複雑なことをやるとかえって見通しが悪くなるので、これくらいで良いのです。
75
75
 
76
76
  余談ですが、本当は私が先に思いついたのは下の例の方です。「まずは1問だけ採点する関数を作ろう。そうすれば、あとはできたも同然だ。そのために、まずは異なり文字数を数える関数を作るか」というような発想で書きました。参考にしてください。
77
77
 

2

編集

2018/04/12 05:00

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -71,7 +71,7 @@
71
71
  main()
72
72
  ```
73
73
 
74
- すっきりしたといえばすっきりしし、コード行数は大して減ってはいないという見方もできるでしょう。でもコードの素直さか読みやすさ損なってまで短より、この方が良い場合も多いのです。
74
+ すっきりしたといえばすっきりしたが、コード行数は大して減ってはいないという見方もできるでしょう。だけどれ、これ以上複雑なことをやるとかえって見通しが悪ので、これくらいで良いのです。
75
75
 
76
76
  余談ですが、本当は私が先に思いついたのは下の例の方です。「まずは1問だけ採点する関数を作ろう。そうすれば、あとはできたも同然だ。そのために、まずは異なり文字数を数える関数を作るか」というような発想で書きました。参考にしてください。
77
77
 

1

追記

2018/04/12 05:00

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -73,4 +73,16 @@
73
73
 
74
74
  すっきりしたといえばすっきりしたし、コード行数は大して減ってはいないという見方もできるでしょう。でもコードの素直さとか読みやすさを損なってまで短くするより、この方が良い場合も多いのです。
75
75
 
76
- 余談ですが、本当は私が先に思いついたのは下の例の方です。「まずは1問だけ採点する関数を作ろう。そうすれば、あとはできたも同然だ。そのために、まずは異なり文字数を数える関数を作るか」というような発想で書きました。参考にしてください。
76
+ 余談ですが、本当は私が先に思いついたのは下の例の方です。「まずは1問だけ採点する関数を作ろう。そうすれば、あとはできたも同然だ。そのために、まずは異なり文字数を数える関数を作るか」というような発想で書きました。参考にしてください。
77
+
78
+ ### 追記
79
+ 「lambda式は複雑な処理にはあまり適しません」と書いてしまいましたが、あえてlambdaバージョンのsaitenを作ってみた例。
80
+ ```python
81
+ saiten = lambda true_ans, exam_ans:(
82
+ 0
83
+ if len(true_ans) != len(exam_ans) else
84
+ (lambda count_diff:(
85
+ [2, 1][count_diff] if count_diff <= 1 else 0))(
86
+ sum([1 for c1, c2 in zip(true_ans, exam_ans) if c1 != c2])))
87
+ ```
88
+ ご覧の通り可読性は悪いのですが、できなくはありません。