|
141 | 141 | >>> {0:1, **{0:2}, 0:3, 0:4} |
142 | 142 | {0: 4} |
143 | 143 |
|
144 | | -List comprehension element unpacking |
| 144 | +Comprehension element unpacking |
145 | 145 |
|
146 | 146 | >>> a, b, c = [0, 1, 2], 3, 4 |
147 | 147 | >>> [*a, b, c] |
148 | 148 | [0, 1, 2, 3, 4] |
149 | 149 |
|
150 | 150 | >>> l = [a, (3, 4), {5}, {6: None}, (i for i in range(7, 10))] |
151 | 151 | >>> [*item for item in l] |
| 152 | + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
| 153 | +
|
| 154 | + >>> [*[0, 1] for i in range(5)] |
| 155 | + [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] |
| 156 | +
|
| 157 | + >>> [*'a' for i in range(5)] |
| 158 | + ['a', 'a', 'a', 'a', 'a'] |
| 159 | +
|
| 160 | + >>> [*[] for i in range(10)] |
| 161 | + [] |
| 162 | +
|
| 163 | + >>> [*(x*2) for x in [[1, 2, 3], [], 'cat']] |
| 164 | + [1, 2, 3, 1, 2, 3, 'c', 'a', 't', 'c', 'a', 't'] |
| 165 | +
|
| 166 | + >>> {**{} for a in [1]} |
| 167 | + {} |
| 168 | +
|
| 169 | + >>> {**{7: i} for i in range(10)} |
| 170 | + {7: 9} |
| 171 | +
|
| 172 | + >>> dicts = [{1: 2}, {3: 4}, {5: 6, 7: 8}, {}, {9: 10}, {1: 0}] |
| 173 | + >>> {**d for d in dicts} |
| 174 | + {1: 0, 3: 4, 5: 6, 7: 8, 9: 10} |
| 175 | +
|
| 176 | + >>> gen = (*(0, 1) for i in range(5)) |
| 177 | + >>> next(gen) |
| 178 | + 0 |
| 179 | + >>> list(gen) |
| 180 | + [1, 0, 1, 0, 1, 0, 1, 0, 1] |
| 181 | +
|
| 182 | +Comprehension unpacking with conditionals and double loops |
| 183 | +
|
| 184 | + >>> [*[i, i+1] for i in range(5) if i % 2 == 0] |
| 185 | + [0, 1, 2, 3, 4, 5] |
| 186 | +
|
| 187 | + >>> [*y for x in [[[0], [1, 2, 3], [], [4, 5]], [[6, 7]]] for y in x] |
| 188 | + [0, 1, 2, 3, 4, 5, 6, 7] |
| 189 | +
|
| 190 | + >>> [*y for x in [[[0], [1, 2, 3], [], [4, 5]], [[6, 7]]] for y in x if y and y[0]>0] |
| 191 | + [1, 2, 3, 4, 5, 6, 7] |
| 192 | +
|
| 193 | + >>> dicts = [{1: 2}, {3: 4}, {5: 6, 7: 8}, {}, {9: 10}, {1: 0}] |
| 194 | + >>> {**d for d in dicts if len(d) != 2} |
| 195 | + {1: 0, 3: 4, 9: 10} |
| 196 | +
|
| 197 | +Scoping of assignment expressions in comprehensions |
| 198 | +
|
| 199 | + >>> [*((y := i**2), 2*y) for i in range(4)] |
| 200 | + [0, 0, 1, 2, 4, 8, 9, 18] |
| 201 | + >>> y |
| 202 | + 9 |
| 203 | +
|
| 204 | + >>> [*(y := [i, i+1, i+2]) for i in range(4)] |
| 205 | + [0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5] |
| 206 | + >>> y |
| 207 | + [3, 4, 5] |
| 208 | +
|
| 209 | + >>> g = (*(z := [i, i+1, i+2]) for i in range(4)) |
| 210 | + >>> z |
| 211 | + Traceback (most recent call last): |
| 212 | + ... |
| 213 | + NameError: name 'z' is not defined |
| 214 | + >>> next(g) |
| 215 | + 0 |
| 216 | + >>> z |
| 217 | + [0, 1, 2] |
| 218 | + >>> next(g) |
| 219 | + 1 |
| 220 | + >>> z |
| 221 | + [0, 1, 2] |
| 222 | + >>> next(g) |
| 223 | + 2 |
| 224 | + >>> z |
| 225 | + [0, 1, 2] |
| 226 | + >>> next(g) |
| 227 | + 1 |
| 228 | + >>> z |
| 229 | + [1, 2, 3] |
| 230 | +
|
| 231 | + >>> x = [1, 2, 3] |
| 232 | + >>> y = [4, 5, 6] |
| 233 | + >>> def f(*args): |
| 234 | + ... print(args) |
| 235 | +
|
| 236 | + >>> f(*x if x else y) |
| 237 | + (1, 2, 3) |
| 238 | +
|
| 239 | +
|
| 240 | +Malformed comperehension element unpacking |
| 241 | +
|
| 242 | + >>> [*x for x in [1, 2, 3]] |
152 | 243 | Traceback (most recent call last): |
153 | 244 | ... |
154 | | - SyntaxError: iterable unpacking cannot be used in comprehension |
| 245 | + [*x for x in [1, 2, 3]] |
| 246 | + ^^ |
| 247 | + TypeError: Value after * must be an iterable, not int |
| 248 | +
|
155 | 249 |
|
156 | | - >>> [*[0, 1] for i in range(10)] |
| 250 | +Error messages for specific failure modes of unpacking |
| 251 | +
|
| 252 | + >>> [*x if x else y for x in z] |
157 | 253 | Traceback (most recent call last): |
158 | 254 | ... |
159 | | - SyntaxError: iterable unpacking cannot be used in comprehension |
| 255 | + [*x if x else y for x in z] |
| 256 | + ^^^^^^^^^^^^^^ |
| 257 | + SyntaxError: invalid starred expression. Did you forget to wrap the conditional expression in parentheses? |
160 | 258 |
|
161 | | - >>> [*'a' for i in range(10)] |
| 259 | + >>> [*x if x else y] |
162 | 260 | Traceback (most recent call last): |
163 | 261 | ... |
164 | | - SyntaxError: iterable unpacking cannot be used in comprehension |
| 262 | + [*x if x else y] |
| 263 | + ^^^^^^^^^^^^^^ |
| 264 | + SyntaxError: invalid starred expression. Did you forget to wrap the conditional expression in parentheses? |
165 | 265 |
|
166 | | - >>> [*[] for i in range(10)] |
| 266 | + >>> [x if x else *y for x in z] |
167 | 267 | Traceback (most recent call last): |
168 | 268 | ... |
169 | | - SyntaxError: iterable unpacking cannot be used in comprehension |
| 269 | + [x if x else *y for x in z] |
| 270 | + ^ |
| 271 | + SyntaxError: cannot unpack only part of a conditional expression |
170 | 272 |
|
171 | | - >>> {**{} for a in [1]} |
| 273 | + >>> [x if x else *y] |
172 | 274 | Traceback (most recent call last): |
173 | 275 | ... |
174 | | - SyntaxError: dict unpacking cannot be used in dict comprehension |
| 276 | + [x if x else *y] |
| 277 | + ^ |
| 278 | + SyntaxError: cannot unpack only part of a conditional expression |
175 | 279 |
|
176 | | -# Pegen is better here. |
177 | | -# Generator expression in function arguments |
| 280 | + >>> {**x if x else y} |
| 281 | + Traceback (most recent call last): |
| 282 | + ... |
| 283 | + {**x if x else y} |
| 284 | + ^^^^^^^^^^^^^^^^ |
| 285 | + SyntaxError: invalid double starred expression. Did you forget to wrap the conditional expression in parentheses? |
| 286 | + >>> {x if x else **y} |
| 287 | + Traceback (most recent call last): |
| 288 | + ... |
| 289 | + {x if x else **y} |
| 290 | + ^^ |
| 291 | + SyntaxError: cannot use dict unpacking on only part of a conditional expression |
| 292 | +
|
| 293 | + >>> [**x for x in [{1: 2}]] |
| 294 | + Traceback (most recent call last): |
| 295 | + ... |
| 296 | + [**x for x in [{1: 2}]] |
| 297 | + ^^^ |
| 298 | + SyntaxError: cannot use dict unpacking in list comprehension |
178 | 299 |
|
179 | | -# >>> list(*x for x in (range(5) for i in range(3))) |
180 | | -# Traceback (most recent call last): |
181 | | -# ... |
182 | | -# list(*x for x in (range(5) for i in range(3))) |
183 | | -# ^ |
184 | | -# SyntaxError: invalid syntax |
| 300 | + >>> (**x for x in [{1:2}]) |
| 301 | + Traceback (most recent call last): |
| 302 | + ... |
| 303 | + (**x for x in [{1:2}]) |
| 304 | + ^^^ |
| 305 | + SyntaxError: cannot use dict unpacking in generator expression |
185 | 306 |
|
186 | 307 | >>> dict(**x for x in [{1:2}]) |
187 | 308 | Traceback (most recent call last): |
188 | 309 | ... |
189 | 310 | dict(**x for x in [{1:2}]) |
190 | | - ^ |
191 | | - SyntaxError: invalid syntax |
| 311 | + ^^^ |
| 312 | + SyntaxError: cannot use dict unpacking in generator expression |
| 313 | +
|
| 314 | + >>> {*a: b for a, b in {1: 2}.items()} |
| 315 | + Traceback (most recent call last): |
| 316 | + ... |
| 317 | + {*a: b for a, b in {1: 2}.items()} |
| 318 | + ^^ |
| 319 | + SyntaxError: cannot use a starred expression in a dictionary key |
| 320 | +
|
| 321 | + >>> {**a: b for a, b in {1: 2}.items()} |
| 322 | + Traceback (most recent call last): |
| 323 | + ... |
| 324 | + {**a: b for a, b in {1: 2}.items()} |
| 325 | + ^^^ |
| 326 | + SyntaxError: cannot use dict unpacking in a dictionary key |
| 327 | +
|
| 328 | + >>> {a: *b for a, b in {1: 2}.items()} |
| 329 | + Traceback (most recent call last): |
| 330 | + ... |
| 331 | + {a: *b for a, b in {1: 2}.items()} |
| 332 | + ^^ |
| 333 | + SyntaxError: cannot use a starred expression in a dictionary value |
| 334 | +
|
| 335 | + >>> {a: **b for a, b in {1: 2}.items()} |
| 336 | + Traceback (most recent call last): |
| 337 | + ... |
| 338 | + {a: **b for a, b in {1: 2}.items()} |
| 339 | + ^^^ |
| 340 | + SyntaxError: cannot use dict unpacking in a dictionary value |
| 341 | +
|
| 342 | +
|
| 343 | +# Pegen is better here. |
| 344 | +# Generator expression in function arguments |
| 345 | +
|
| 346 | + >>> list(*x for x in (range(5) for i in range(3))) |
| 347 | + [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4] |
| 348 | +
|
| 349 | + >>> def f(arg): |
| 350 | + ... print(type(arg), list(arg), list(arg)) |
| 351 | + >>> f(*x for x in [[1,2,3]]) |
| 352 | + <class 'generator'> [1, 2, 3] [] |
192 | 353 |
|
193 | 354 | Iterable argument unpacking |
194 | 355 |
|
|
0 commit comments