简体   繁体   English

Python:for-in循环未检查列表中的最后一个字符串,为什么?

[英]Python: for-in loop is not checking the last string in a list, why?

I'm using a for-in loop to remove any strings from a list titled "words" that start with "x" as part of a function, but find that this loop will not check the last string in the list. 我正在使用for-in循环从函数中以“ x”开头的标题为“ words”的列表中删除所有字符串,但发现该循环不会检查列表中的最后一个字符串。 Why is this? 为什么是这样?

After adding some print statements to figure out where things were going wrong I narrowed it down to the second for-in loop, but beyond that I'm not sure what to do... 添加一些打印语句以找出问题所在后,我将其范围缩小到第二个for-in循环,但除此之外,我不确定该怎么做...

def front_x(words):
  print '\n'
  words.sort()
  print words
  words2 = []
  for string in words:
    if string[0] == 'x':
      words2.append(string)
      #print 'added ' + string + ' to words2'
    #else:
      #print '(append)checked ' + string
  for string in words:
    if string[0] == 'x':
      words.remove(string)
      print 'removed ' + string
    else: print 'checked ' + string
  words2.extend(words)
  return words2

As you can see, in each case it will check all of the elements in the list printed above except for the last. 如您所见,在每种情况下,它将检查上面打印的列表中除最后一个元素之外的所有元素。 Below that are what my program got vs what it is supposed to get. 在此之下是我的程序得到的与应该得到的。

['axx', 'bbb', 'ccc', 'xaa', 'xzz']
checked axx
checked bbb
checked ccc
removed xaa
X  got: ['xaa', 'xzz', 'axx', 'bbb', 'ccc', 'xzz'] 
expected: ['xaa', 'xzz', 'axx', 'bbb', 'ccc']


['aaa', 'bbb', 'ccc', 'xaa', 'xcc']
checked aaa
checked bbb
checked ccc
removed xaa
X  got: ['xaa', 'xcc', 'aaa', 'bbb', 'ccc', 'xcc'] 
expected: ['xaa', 'xcc', 'aaa', 'bbb', 'ccc']


['aardvark', 'apple', 'mix', 'xanadu', 'xyz']
checked aardvark
checked apple
checked mix
removed xanadu
X  got: ['xanadu', 'xyz', 'aardvark', 'apple', 'mix', 'xyz']
expected: ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']

I think you need this to get a list as you expected result looks like: 我认为您需要它来获取列表,因为预期结果如下所示:

not_xes = [i for i in words if not i.startswith('x')]
xes = [i for i in words if i.startswitch('x')]
expected_result = xes + not_xes

You are mutating the list as you are iterating over it. 您正在遍历列表时对其进行变异。 Behind the scenes Python is stepping through the numeric index of each item in the list. 在后台,Python正在逐步浏览列表中每个项目的数字索引。 When you remove an item, all of the items with a higher index are shifted. 删除项目时,所有索引较高的项目都会移动。

Instead, build an list of the indices you want to remove, then remove them. 而是,构建要删除的索引的列表,然后将其删除。 Or use a list comprehension to build a new list. 或使用列表理解来构建新列表。

def front_x(words):
    words2 = [w for w in words if w.startswith('x')]
    return words2

If you want to also mutate the original list (modify words ) with the function you can do so using: 如果您还想使用该功能来更改原始列表(修改words ),则可以使用以下方法:

def drop_front_x(words):
    words2 = []
    indices = [i for i, w in enumerate(words) if w.startswith('x')]
    for ix in reversed(indices):
        words2.insert(0, words.pop(ix))
    return words2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM