Python社区  »  Python

Python3.8对「可迭代解包」的改进

Python之美 • 3 月前 • 39 次点击  


标题想了很久,最终还是直接表述了。O(∩_∩)O

Python 3的可迭代解包

在 PEP 3132 - Extended Iterable Unpacking里面描述了一种对可迭代对象的解包用法,Python 3可用:

  1. In : a, *b, c = range(5)


  2. In : a, c

  3. Out: (0, 4)


  4. In : b

  5. Out: [1, 2, 3]


  6. In : *a, = range(5)


  7. In : a

  8. Out: [0, 1, 2, 3, 4]


  9. In : for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:

  10. ...: print(b)

  11. ...:

  12. [2, 3]

  13. [ 5, 6, 7]

挺方便的,ES6也有对应的 destructuring assignment语法实现解包数组,不过人家实现的更彻底,还可以解包对象。

不过在Python 3.2时引入了一个BUG。看一个例子:

  1. In : def a():

  2. ...: rest = (4, 5, 6)

  3. ...: t = 1, 2, 3, *rest

  4. ...: return t

  5. ...:


  6. In : for i in a():

  7. ...: print(i)

  8. ...:

  9. 1

  10. 2

  11. 3

  12. 4

  13. 5

  14. 6

其实这是一个非常简化的写法,要不然需要把1,2,3放在一个元组中,再+rest:

  1. In : (1, 2, 3) + (3, 4, 5, 6)

  2. Out: (1, 2, 3, 4, 5, 6)

但是上面这个例子稍微改一下:

  1. In : def b():

  2. ...: rest = (4, 5, 6)

  3. ...: return 1, 2, 3, *rest

  4. File " ", line 3

  5. return 1, 2, 3, *rest

  6. ^

  7. SyntaxError: invalid syntax

不用变量t, 直接返回就会抛SyntaxError,另外就是yield(当然要注意return和yield本身的意见不同啊):

  1. In : def c():

  2. ...: rest = (4, 5 , 6)

  3. ...: yield 1, 2, 3, *rest

  4. File "", line 3

  5. yield 1, 2, 3, *rest

  6. ^

  7. SyntaxError: invalid syntax

Python 3.8

在Python 3.8,修复了这个问题:

  1. >>> def b():

  2. ... rest = (4, 5, 6)

  3. ... return 1, 2, 3, *rest

  4. ...

  5. >>> for i in b():

  6. ... print(i)

  7. ...

  8. 1

  9. 2

  10. 3

  11. 4

  12. 5

  13. 6

  14. >>> def c():

  15. ... rest = (4, 5, 6)

  16. ... yield 1, 2, 3, *rest

  17. ...

  18. >>> for i in c():

  19. ... print(i)

  20. ...

  21. (1, 2, 3, 4, 5, 6)

你学到了么?

延伸阅读

  1. PEP 3132

  2. Tuple unpacking in return and yield statements

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/37550
 
39 次点击  
分享到微博