通过切片不知道这在python中做了什么

时间:2016-04-14 17:58:04

标签: python slice

以下是设置:

words = ['cat', 'window', 'defenestrate']
    for w in words:
        print(w, len(w))

然后我输入:

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...

我不明白insert(0, w)中的0是什么    这样做。当我用另一个数字改变它    输出保持不变。

最终输入/输出:

>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

4 个答案:

答案 0 :(得分:3)

insert的第一个参数告诉insert将新项目放在列表中的索引。由于您只有一个超过6个字符的单词,因此您发布的代码会将defenestrate添加到现有列表的开头。

来自docs

  

list.insert(i,x)

     

在指定位置插入项目。第一个参数是要插入的元素的索引,因此a.insert(0,x)插入列表的前面,而a.insert(len(a),x)等同于a.append( x)的

答案 1 :(得分:1)

  

我不明白插入(0,w)中的0是什么。当我用另一个数字改变它时,输出保持不变。

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...

我之前遇到过python教程的这个问题,这是我的解释。

让我们退一步看看背景:

这个例子来自python教程的第4章,但是你正在质疑的代码行引用了同一个教程的第5.1章。

列表上的'insert'方法在这里: https://docs.python.org/2.7/tutorial/datastructures.html

如果您按顺序执行教程,那么这种混淆是可以理解的,当然,您应该这样做,然后您不熟悉这行代码。跳到第5.1章,看看:

  

list.insert(i,x)在给定位置插入一个项目。首先   argument是要插入的元素的索引,所以   a.insert(0,x)插入列表的前面,a.insert(len(a),   x)相当于a.append(x)。

作者试图表明的一点是,您希望在修改循环内的列表之前复制列表,否则可能会发生“坏事”。

请参阅:Thou Shalt Not Modify A List During Iteration

如果你不复制列表,循环永远不会完成...试试这个:

>>> for w in words:  # Loop over the list, and modify it while looping
...     if len(w) > 6:
...         words.insert(0, w)
...

你会等到内存耗尽,但是你得到了这个:

['defenestrate', 'defenestrate', 'defenestrate', 'defenestrate', 'defenestrate', 'defenestrate', 'defenestrate', 'defenestrate', 'defenestrate', 'defenestrate', 'cat', 'window', 'defenestrate']

原因是:

  1. for循环从words[0]获取'w':'cat'
    • len('cat') > 6false - 继续
  2. for循环从words[1]获取'w':'window'
    • len('window') > 6false - 继续
  3. for循环从words[2]获取'w':'defenestrate'
    • len('defenstrate') > 6true
    • 插入...
    • words现在是['defenestrate', 'cat', 'window', 'defenestrate']
  4. for循环从words[3]获取'w':'defenstrate'
    • len('defenstrate') > 6true
    • 插入...
    • words现在是['defenstrate, 'defenestrate', 'cat', 'window', 'defenestrate']
  5. for循环从words[4]获取'w':'defenstrate'
  6. ...继续无限。

    复制列表时,会发生这种情况:

    1. for循环从words[3]的副本中获取'w'
      • 引发异常:IndexError(因为words的复制只有3个项目)
      • for循环通过终止循环来处理异常。
    2. 您从未更改过“词汇”列表的副本 您正在更改原始的“字词”列表。

      副本是匿名。它是一个仅用于控制循环的变量,仅在循环内部可用。当循环终止时它会消失。

答案 2 :(得分:0)

更改插入位置应更改输出,如下所示。插入位置(如你所说的'0')告诉列表中要插入的索引。

>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words[:]:
...   if len(w) > 6:
...     words.insert(0,w)
... 
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words[:]:
...   if len(w) > 6:
...     words.insert(2,w)
... 
>>> words
['cat', 'window', 'defenestrate', 'defenestrate']

答案 3 :(得分:0)

0中的(0, w)是将插入单词(w)的索引。

因此,您的代码基本上是在列表中进行迭代,并在列表的开头放置长度超过6个字符的任何单词。

对我来说,更改索引的工作方式正如您所期望的那样。

索引0

In [1]: words = ['cat', 'window', 'defenestrate']

In [2]: for w in words[:]:
    ...:     if len(w) > 6:
    ...:         words.insert(0, w)
    ...:

In [3]: words
Out[3]: ['defenestrate', 'cat', 'window', 'defenestrate']

索引1

In [1]: words = ['cat', 'window', 'defenestrate']

In [2]: for w in words[:]:
    if len(w) > 6:
        words.insert(1, w)
    ...:

In [3]: words
Out[3]: ['cat', 'defenestrate', 'window', 'defenestrate']

索引3

In [1]: words = ['cat', 'window', 'defenestrate']

In [2]: for w in words[:]:
    if len(w) > 6:
        words.insert(3, w)
   ...:

In [3]: words
Out[3]: ['cat', 'window', 'defenestrate', 'defenestrate']