52

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

 4 years ago
source link: https://www.tuicool.com/articles/iieuiqU
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

Python 3的可迭代解包

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

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

In : a, c
Out: (0, 4)

In : b
Out: [1, 2, 3]

In : *a, = range(5)

In : a
Out: [0, 1, 2, 3, 4]

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

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

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

In : def a():
...:     rest = (4, 5, 6)
...:     t = 1, 2, 3, *rest
...:     return t
...:

In : for i in a():
...:     print(i)
...:
1
2
3
4
5
6

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

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

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

In : def b():
...:     rest = (4, 5, 6)
...:     return 1, 2, 3, *rest
File "<ipython-input-38-b5a7115853e2>", line 3
  return 1, 2, 3, *rest
                    ^
SyntaxError: invalid syntax

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

In : def c():
...:     rest = (4, 5, 6)
...:     yield 1, 2, 3, *rest
File "<ipython-input-39-cf6991fcff64>", line 3
  yield 1, 2, 3, *rest
                   ^
SyntaxError: invalid syntax

Python 3.8

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

>>> def b():
...     rest = (4, 5, 6)
...     return 1, 2, 3, *rest
...
>>> for i in b():
...     print(i)
...
1
2
3
4
5
6
>>> def c():
...     rest = (4, 5, 6)
...     yield 1, 2, 3, *rest
...
>>> for i in c():
...     print(i)
...
(1, 2, 3, 4, 5, 6)

你学到了么?

延伸阅读


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK