0

如何在每次迭代中更新循环的上限?在下面的代码中,List 在每个循环中都会被缩短。但是,for, in 循环中的 lenList 不是,即使我将 lenList 定义为全局。任何想法如何解决这个问题?(我正在使用 Python 2.sthg)谢谢!

def similarity(List):
import difflib
lenList = len(List)
for i in range(1,lenList):
    import numpy as np
    global lenList
    a = List[i]
    idx = [difflib.SequenceMatcher(None, a, x).ratio() for x in List]
    z = idx > .9
    del List[z]
    lenList = len(List)


X = ['jim','jimmy','luke','john','jake','matt','steve','tj','pat','chad','don']
similarity(X)
4

5 回答 5

2

在 python 中循环索引是不好的做法。不过,您也许可以像这样完成您想要的(编辑评论):

def similarity(alist):
  position = 0
  while position < len(alist):
    item = alist[position]
    position += 1
    # code here that modifies alist

列表将评估True它是否有任何条目,或者False它何时为空。通过这种方式,您可以使用在操作其项目期间可能会增长的列表。

此外,如果你绝对必须有索引,你也可以得到这些:

for idx, item in enumerate(alist):
  # code here, where items are actual list entries, and 
  # idx is the 0-based index of the item in the list.

在 ... 3.x(我相信)中,您甚至可以传递一个可选参数来枚举以控制idx.

于 2012-12-05T04:27:50.370 回答
1

这里的问题是,range()它只在循环开始时评估一次,并在那时产生一个范围生成器(或 2.x 中的列表)。然后您无法更改范围。更不用说数字和不可变了,因此您正在为 分配一个新值lenList,但这不会影响它的任何用途。

最好的解决方案是改变你的算法的工作方式,而不是依赖这种行为。

于 2012-12-05T04:27:42.930 回答
0

Therange是在循环的第一次迭代之前构造的对象,因此您正在迭代该对象中的值。相反,您将需要使用 while 循环,尽管正如 Lattyware 和 gddc 指出的那样,它不会很 Pythonic。

于 2012-12-05T04:29:06.273 回答
0

您在上面的代码中有效循环的是在第一次迭代本身中生成的列表。

你也可以把上面写成

li = range(1,lenList)
for i in li:
    ... your code ...

在创建 li 后更改 lenList 对 li 没有影响

于 2012-12-05T04:29:31.920 回答
0

只要对函数的工作方式进行一点小修改,这个问题就会变得容易得多:不要从现有列表中删除类似的项目,而是创建并返回一个省略了这些项目的新项目。

对于仅删除与第一个项目的相似性的特定情况这简化了很多,并且不需要涉及 Numpy 的花哨索引(因为缺少对 的调用,您实际上并没有使用它np.array):

import difflib

def similarity(lst): 
    a = lst[0]
    return [a] + \
       [x for x in lst[1:] if difflib.SequenceMatcher(None, a, x).ratio() > .9]

在此基础上,可以递归地对列表中的每个项目重复它- 您需要将最后的列表理解传递回similarity,并处理接收一个空列表:

def similarity(lst):
   if not lst: 
       return []
   a = lst[0]
   return [a] + similarity(
        [x for x in lst[1:] if difflib.SequenceMatcher(None, a, x).ratio() > .9])

另请注意,在函数内部导入和命名变量list(隐藏内置list)都是值得避免的做法,因为它们会使您的代码更难遵循。

于 2012-12-05T05:14:44.563 回答