1
mylist="'a','b','c'"

count=0
i=0

while count< len(mylist):
    if mylist[i]==mylist[i+1]:
        print mylist[i]
    count +=1
    i +=1

错误:

File "<string>", line 6, in <module>
IndexError: string index out of range

我假设当它到达最后一个(第 n 个)元素时,它找不到 n+1 来比较它,所以它给了我一个错误。

有趣的是,我认为我以前做过这个并且没有在更大的列表中遇到这个问题:这是一个例子(感谢 Raymond Hettinger 修复它)

list=['a','a','x','c','e','e','f','f','f']

i=0
count = 0

while count < len(list)-2:
    if list[i] == list[i+1]:
        if list [i+1] != list [i+2]:
            print list[i]
            i+=1
            count +=1
        else:
            print "no"
            count += 1
    else:   
        i +=1
        count += 1

对于以我尝试过的方式在列表中爬行,是否有任何解决方法使我不会“超出范围”?我计划在一个非常大的列表上实现它,例如,我必须检查“list[i]==list[i+16]”。将来,我想添加“if int(mylist[i+3])-int(mylist[i+7])>10: newerlist.append[mylist[i]”等条件。所以解决这个问题很重要。

我想过插入一个break语句,但没有成功。

我知道这不是最有效的,但我正处于我最了解的地步。

4

4 回答 4

5

因此,听起来您正在尝试以各种固定偏移量比较列表中的元素。也许这样的事情可以帮助你:

for old, new in zip(lst, lst[n:]):
    if some_cond(old, new):
        do_work()

解释:

lst[n:]返回 lst 的副本,从第 n 个(注意 0 索引)元素开始

>>> lst = [1,2,2,3];
>>> lst[1:]
[2,2,3]

zip(l1, l2)创建一个新的元组列表,每个列表都有一个元素

>>> zip(lst, lst[1:])
[(1, 2), (2, 2), (2, 3)]

请注意,只要任一列表用完,它就会停止。在这种情况下,偏移量列表首先用完。

对于元组列表,您可以在循环变量中“直接打包”,所以

for old, new in zip(lst, lst[1:])

通过您想要的元素循环(列表中的连续元素对)

于 2013-05-19T15:01:31.623 回答
1

一般来说,如果你试图向前看一定数量的地方,你可以做一些事情:

  1. 在循环检查(即计数 < 长度)中,您需要检查最大字段。所以在你的例子中,你想去 16 个空格。这意味着您需要检查 count < (length - 16)。缺点是您的最后一个元素(最后 16 个)不会被迭代。

  2. 检查循环内部以确保索引适用。也就是说,每个 if 语句都以:if(I+16 < length && logic_you_want_to_check) 开头。这将允许您继续循环,但是当逻辑由于超出范围而失败时,您不会出错。

  3. 注意 - 这可能不是你想要的,但为了完整起见,我会添加它。围绕你的逻辑。这只有在可以考虑环绕时才有效。如果您确实想在当前索引之前检查第 16 个索引(即,可能像一行中的一个位置),那么环绕并不适合。但是,如果不需要该逻辑,并且想以循环模式对值进行建模,则可以对索引进行模数。也就是说:如果 array[i] == array [(i + 16)%length(array)] 将检查前面的 16 或绕到数组的前面。

于 2013-05-19T15:03:51.033 回答
-1

编辑:

对,有了 OP 中的新信息,这变得简单多了。使用配方itertools grouper()每个人的数据分组为元组:

import itertools

def grouper(iterable, n, fillvalue=None):
    """Collect data into fixed-length chunks or blocks"""
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

data = ['John', 'Sally', '5', '10', '11', '4', 'John', 'Sally', '3', '7', '7', '10', 'Bill', 'Hallie', '4', '6', '2', '1']

grouper(data, 6)

现在您的数据如下所示:

[
    ('John', 'Sally', '5', '10', '11', '4'), 
    ('John', 'Sally', '3', '7', '7', '10'), 
    ('Bill', 'Hallie', '4', '6', '2', '1')
]

相比之下,这应该很容易使用。


老答案:

如果您需要创建更多任意链接,而不仅仅是检查连续值:

def offset_iter(iterable, n):
    offset = iter(iterable)
    consume(offset, n)
    return offset

data = ['a', 'a', 'x', 'c', 'e', 'e', 'f', 'f', 'f']

offset_3 = offset_iter(data, 3)

for item, plus_3 in zip(data, offset_3): #Naturally, itertools.izip() in 2.x
    print(item, plus_3)                  #if memory usage is important.

自然,您会希望使用语义上有效的名称。这种方法的优点是它适用于任意迭代,而不仅仅是列表,并且高效且可读,没有任何丑陋、低效的索引迭代。如果您需要在偏移值用完后继续检查(例如,对于其他条件),请使用itertools.zip_longest()itertools.izip_longest()在 2.x 中)。

使用来自consume()食谱itertools

import itertools
import collections

def consume(iterator, n):
    """Advance the iterator n-steps ahead. If n is none, consume entirely."""
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(itertools.islice(iterator, n, n), None)

但是,我会非常怀疑在这种情况下您是否需要重新检查您的数据结构。


原答案:

我不确定你的目标是什么,但从我收集到的你可能想要itertools.groupby()

>>> import itertools
>>> data = ['a', 'a', 'x', 'c', 'e', 'e', 'f', 'f', 'f']
>>> grouped = itertools.groupby(data)
>>> [(key, len(list(items))) for key, items in grouped]
[('a', 2), ('x', 1), ('c', 1), ('e', 2), ('f', 3)]

当有(任意大)重复项目运行时,您可以使用它来解决问题。值得注意的是,您可以提供itertools.groupby()一个key参数,该参数将根据您想要的任何因素对它们进行分组,而不仅仅是平等。

于 2013-05-19T14:55:57.450 回答
-2

如果你坚持“实用胜于纯粹”

for idx, element in enumerate(yourlist[n:]):
    if yourlist[idx] == yourlist[idx-n]
    ...

如果您不关心内存效率,请选择第二个答案。如果您想要最纯粹的答案,请选择 Lattyware 的答案。

于 2013-05-19T14:49:46.827 回答