Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个Python语句是什么意思?_Python - Fatal编程技术网

这个Python语句是什么意思?

这个Python语句是什么意思?,python,Python,我正在编写一个解析器,在调试它的过程中,我发现这显然是合法的Python: for [] in [[]]: print 0 这也是(!): 我不怪解析器搞混了。。。我弄不清楚怎么解释它 这句话到底是什么意思?就执行而言:没有 for循环本身在空列表上循环,因此不会发生迭代 这是一件好事,因为[]的意味着:将循环中的每个条目分配给0个变量。后一部分可能让你感到困惑 该语句是合法的,因为允许您将序列中的值分配给同样大的变量名序列;我们称之为元组解包。以下是分配和删除中更有用的目标列表示例:

我正在编写一个解析器,在调试它的过程中,我发现这显然是合法的Python:

for []    in [[]]: print 0
这也是(!):

我不怪解析器搞混了。。。我弄不清楚怎么解释它


这句话到底是什么意思?

就执行而言:没有

for
循环本身在空列表上循环,因此不会发生迭代

这是一件好事,因为[]的
意味着:将循环中的每个条目分配给0个变量。后一部分可能让你感到困惑

该语句是合法的,因为允许您将序列中的值分配给同样大的变量名序列;我们称之为元组解包。以下是分配和删除中更有用的目标列表示例:

(a, b, c) = range(3)
del a, b, c
您可以在
for
循环中执行相同的操作:

nested = [[1,2,3], [4,5,6]]
for a, b, c in nested:
    print nested
您可以对
target\u list
标记同时使用元组和列表,这也是合法的:

[a, b] = (1, 2)
但是,在Python中,列表可以为空。因此,以下内容是合法的,但不合理:

[] = []
for [][:] in [range(i) for i in range(10)]: print 0
最后,这也是:

nested_empty = [[], [], []]
for [] in nested_empty:
    pass
目标列表更有趣:

[][:] = [1, 2, 3]
现在左手边在赋值中使用了一个切片。从文件中:

如果目标是切片:将计算引用中的主表达式。它应该产生一个可变序列对象(如列表)。指定的对象应该是相同类型的序列对象。接下来,计算下限和上限表达式,只要它们存在;默认值为零和序列的长度。边界应计算为(小)整数。如果任意一个边界为负,则序列的长度将添加到该边界中。生成的边界被剪裁为介于零和序列长度之间(包括零和序列长度)。最后,要求sequence对象用指定序列的项目替换切片。切片的长度可能不同于指定序列的长度,因此,如果对象允许,可以更改目标序列的长度

所以这里我们不再使用元组解包;相反,我们用右侧列表替换左侧列表的一部分。但是,因为在我们的示例中,左边的列表是一个匿名列表文字,所以结果更改的列表再次丢失

但是,由于这样的赋值在for循环中也是合法的,因此以下是合法的语法,尽管有些不合理:

[] = []
for [][:] in [range(i) for i in range(10)]: print 0
这相当于:

In [44]: for [x,y] in [[1,2],[3,4],[5,6]]: # or even (x,y) will work
    print x,y
   ....:     
   ....:     
1 2
3 4
5 6
但前者期望列表中不返回任何值,即列表中的值要么为空,要么其
len()
0

您不能在那里使用
()
,因为它不是有效的

因为在python中,可以按如下方式分配alss:

In [56]: x,y=[1,2]      #this means that the expression on RHS should return two values
                        # (x,y)=[1,2] or x,y=(1,2) or (x,y)=(1,2) all are valid

In [57]: x
Out[57]: 1

In [58]: y
Out[58]: 2


In [62]: x,y='ab'     #assign a to x and b to y

In [63]: x
Out[63]: 'a'

In [64]: y
Out[64]: 'b'
下面是我最好的猜测:

对于[]中的[]
表示“对于此列表中的每个实例,
[[]]
(一个空列表对象)。
打印0


在第二种情况下,我认为
[:]
只需调用
slice()
使用所有默认值,这将只占用整个列表的一部分。在内部,这可能会做一些事情,例如复制列表对象,但在本例中效果应该相同。

Python手册中描述了for..in结构

关键字中的
左侧可以有多个变量

for [i,j] in [(1,2),(3,4),(5,6)]:
  print i, j

for [i,j] in [[1,2],[3,4],[5,6]]:
  print i, j
手册上说它的解释如下

i,j = (1,2)
对于第一次迭代,依此类推。因此,您可以有一个空的变量列表,因为迭代的列表只有一个空列表作为元素。此循环将打印一次0

您正在阅读的解析器,它是自动生成的吗?这种语句可以由非人工源生成。我看不出它的用途

for []    in [[]]: print 0
表示对于[]中的每个空iterables,即包含空列表的列表,打印0。它不仅限于列表,而且每个iterables都可以放入其中。例如,您可以尝试:

# empty list, empty tuple, empty string, empty unicode
for [] in [[], (), '', unicode()]: print 0
它会打印四次0


[][:]与[]相同。它将返回一个空列表,因此我的答案与上面的相同。

假设您有一个元组列表,如下所示:

L = [(1,2), (3,4), (5,6)]
假设要以某种特殊方式打印这些元组:

for tup in L:
    a = tup[0]
    b = tup[1]
    if a<b:
        print a,b
    else:
        print b,a
但你可以让它更不乏味:

for (a,b) in L: # you could also do "for [a,b] in L"
    if a<b:
        print a,b
    else:
        print b,a

…还有这种行为:

>>> x,y = (2,5,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack

>>> for [] in [[], [5]]: print 0
... 
0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack

因此,当您调用
[][:]
时,您所做的只是创建一个新的空列表,其工作原理与我对您的第一个示例的解释相同

啊,这解释了为什么[[]]中的[]的
:打印0
有效,但是[[]]中的[]的[]的
如何:print 0
?这怎么合法/是什么意思?列表不是空的。它包含一个元素,即空列表。因此,0将被打印。@Mehrdad:左侧的
target\u list
可以是片分配。
alist[1:2]
=somelist`替换
[1:2]指示的片
根据
somelist
的值。因此,切片是赋值的有效左侧表达式,在循环中也是有效的。@ValentinPerrelle:这已经很清楚了,循环中的切片分配才是有趣的一点。@MartijnPieters:我不明白。是的,零被打印出来了,但是[[]中[][:]的
是什么意思:
甚至是什么意思?注意:因为我在这台机器上没有访问Python的权限,所以我的猜测基于Skulpt的结果,它打印了
0
。我假设Skulpt()正在做与CPython相同的事情,这在本案例中不一定是一个安全的假设。重要的部分是手册中的
target
atom,它定义了一个左侧站点法律表达式。谷歌用于序列解包。应该解释一下。
>>> for i in 5: print i
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

>>> for [] in [[], 5]: print 0
... 
0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> x,y = (2,5,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack

>>> for [] in [[], [5]]: print 0
... 
0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>> L = [1,2,3]
>>> M = L
>>> M[0] = 'a'
>>> print L[0]
'a'

>>> L = [1,2,3]
>>> M = L[:]
>>> M[0] = 'a'
>>> print L[0]
1