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

回答編集履歴

7

追記

2021/02/13 14:04

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -130,4 +130,11 @@
130
130
  return sum(
131
131
  price + i - 1 for i in range(3)
132
132
  )
133
+ ```
134
+
135
+ 更には
136
+ ```Python
137
+ def abc(price):
138
+ n = 3
139
+ return n*(price-1) + (n*(n-1)//2)
133
140
  ```

6

追記

2021/02/13 14:04

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -25,6 +25,8 @@
25
25
  funcs.append(lambda e=i: print(f'e = {e}')) # 外部変数iを直接使わない
26
26
  ```
27
27
 
28
+ **参考**: [ループの中で異なる値で定義されたラムダ式が、同じ値を返すのはなぜですか?](https://docs.python.org/ja/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result)
29
+
28
30
  2. リストをデフォルト引数にしない
29
31
  ---
30
32
  Python独特の挙動で、嵌りやすいです。
@@ -55,6 +57,8 @@
55
57
  print(lst)
56
58
  ```
57
59
 
60
+ **参考**: [なぜオブジェクト間でデフォルト値が共有されるのですか?](https://docs.python.org/ja/3/faq/programming.html#why-are-default-values-shared-between-objects)
61
+
58
62
  トレース
59
63
  ---
60
64
  **一つ目のコード**

5

修正

2021/02/13 13:57

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -62,7 +62,8 @@
62
62
  ```Python
63
63
  list=[]
64
64
  for i in range(3):
65
+ list.append(lambda x:x+i-1)
65
- list.append(lambda x:x+i-1) # この時点で全要素が lambda x: x+2-1 になっている
66
+ # ループ終了時点で全要素が lambda x: x+2-1 になっている
66
67
 
67
68
  sum=0
68
69
 
@@ -76,7 +77,8 @@
76
77
  def abc(price,list=[]):
77
78
 
78
79
  for i in range(3):
79
- list.append(lambda x:x+i-1) # 全要素が lambda x: x+2-1
80
+ list.append(lambda x:x+i-1)
81
+                   # 全要素が lambda x: x+2-1
80
82
 
81
83
  sum=0
82
84
 
@@ -93,7 +95,8 @@
93
95
  def abc(price,list=[]): # 関数突入時点で list = [lambda x: x+2-1 が3つ]
94
96
 
95
97
  for i in range(3):
96
- list.append(lambda x:x+i-1) # 全要素が lambda x: x+2-1
98
+ list.append(lambda x:x+i-1)
99
+    # 全要素が lambda x: x+2-1
97
100
 
98
101
  sum=0
99
102
 

4

追記

2021/02/13 13:49

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -66,7 +66,7 @@
66
66
 
67
67
  sum=0
68
68
 
69
- for a in list:
69
+ for a in list: # リスト長は3
70
70
  sum += a(1) # a(1) は常に 1+2-1 = 2 を返す
71
71
  print(sum) # 3回足したら 3x2 = 6
72
72
  ```
@@ -97,10 +97,30 @@
97
97
 
98
98
  sum=0
99
99
 
100
- for a in list:
100
+ for a in list: # リスト長は6
101
101
  sum += a(price) # a(1) は常に 1+2-1 = 2 を返す
102
102
 
103
103
  return sum # 6回足したら 12
104
104
 
105
105
  print(abc(1))
106
+ ```
107
+
108
+ 解決案
109
+ ---
110
+ 少なくとも今回のコードについては、あまり難しく考える必要は無いでしょう。
111
+ ```Python
112
+ def abc(price):
113
+ ret = 0
114
+ for i in range(3):
115
+ ret += price + i - 1
116
+
117
+ return ret
118
+ ```
119
+
120
+ あるいは
121
+ ```Python
122
+ def abc(price):
123
+ return sum(
124
+ price + i - 1 for i in range(3)
125
+ )
106
126
  ```

3

追記

2021/02/13 13:46

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -19,6 +19,12 @@
19
19
  i = 2
20
20
  ```
21
21
 
22
+ 次のように回避する方法が知られています。
23
+ ```Python
24
+ for i in range(3):
25
+ funcs.append(lambda e=i: print(f'e = {e}')) # 外部変数iを直接使わない
26
+ ```
27
+
22
28
  2. リストをデフォルト引数にしない
23
29
  ---
24
30
  Python独特の挙動で、嵌りやすいです。
@@ -39,6 +45,16 @@
39
45
  [0, 1, 2]
40
46
  ```
41
47
 
48
+ 次のように回避する方法が知られています。
49
+ ```Python
50
+ def func(e, lst=None): # デフォルト引数をNoneにする
51
+ if lst is None:
52
+ lst = []
53
+
54
+ lst.append(e)
55
+ print(lst)
56
+ ```
57
+
42
58
  トレース
43
59
  ---
44
60
  **一つ目のコード**

2

追記

2021/02/13 13:43

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -37,4 +37,54 @@
37
37
  [0]
38
38
  [0, 1]
39
39
  [0, 1, 2]
40
+ ```
41
+
42
+ トレース
43
+ ---
44
+ **一つ目のコード**
45
+
46
+ ```Python
47
+ list=[]
48
+ for i in range(3):
49
+ list.append(lambda x:x+i-1) # この時点で全要素が lambda x: x+2-1 になっている
50
+
51
+ sum=0
52
+
53
+ for a in list:
54
+ sum += a(1) # a(1) は常に 1+2-1 = 2 を返す
55
+ print(sum) # 3回足したら 3x2 = 6
56
+ ```
57
+
58
+ **二つ目のコード・前半**
59
+ ```Python
60
+ def abc(price,list=[]):
61
+
62
+ for i in range(3):
63
+ list.append(lambda x:x+i-1) # 全要素が lambda x: x+2-1
64
+
65
+ sum=0
66
+
67
+ for a in list:
68
+ sum += a(price) # a(0) は常に 0+2-1 = 1 を返す
69
+
70
+ return sum # 3回足したら 3
71
+
72
+ print(abc(0))
73
+ ```
74
+
75
+ **二つ目のコード・後半**
76
+ ```Python
77
+ def abc(price,list=[]): # 関数突入時点で list = [lambda x: x+2-1 が3つ]
78
+
79
+ for i in range(3):
80
+ list.append(lambda x:x+i-1) # 全要素が lambda x: x+2-1
81
+
82
+ sum=0
83
+
84
+ for a in list:
85
+ sum += a(price) # a(1) は常に 1+2-1 = 2 を返す
86
+
87
+ return sum # 6回足したら 12
88
+
89
+ print(abc(1))
40
90
  ```

1

修正

2021/02/13 13:37

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -1,4 +1,4 @@
1
- 複合的な、しかもそれぞれが分かりづらい原因です。
1
+ 複合的な、しかもそれぞれが分かりづらい理由挙動を追いづらくなっています。
2
2
 
3
3
  1. ループ中で定義した関数には注意
4
4
  ---