如何在没有错误的情况下检查列表:列表索引超出范围

时间:2018-04-24 17:36:33

标签: python python-3.x list indexing range

我有一个索引列表:

index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]

我得到了:

pattern_width = 4
n = pattern_width
final_list = []

我如何一次遍历分析n个元素的列表,如果所有元素都具有相同的值,它们会被附加到空列表中?

所以,这里前4个元素是[5,5,5,5],值5将附加到final_list。但是,由于接下来的4个元素是[5,5,5,6],因此不会附加。

解决方案将是[5,16,34,42]

我遇到的问题是list index out of range

我的方法是:

for i in range(len(index_max)):
    x = index_max[i]==index_max[i+(pattern_width)
    final_list.append(x)

但是,这不能在列表的末尾工作。我该如何解决这个问题?谢谢。

5 个答案:

答案 0 :(得分:2)

index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]   
n = 4
final_list = [index_max[i] for  i in range(len(index_max)-(n-1)) if len(set(index_max[i:i+n])) == 1]

这应该可以解决问题。打破它,

    如果符合条件,
  1. index_max[i]将返回索引值。
  2. range(len(index_max)-(n-1)) - 这将搜索列表中每个4的组合。 n-1将确保列表在长度为4的最后一个组合上停止。
  3. len(set(index_max[i:i+n])) == 1将测试列表转换为集合。这将允许您根据集合的长度评估唯一值。
  4. 如果您担心列表中的重复值,只需使用如下所示的集合理解,

    final_list = {index_max[i] for  i in range(len(index_max)-(n-1)) if len(set(index_max[i:i+n])) == 1}
    

答案 1 :(得分:1)

您可以尝试以下

index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]
pattern_width = 4
final_list = []

for i in range(len(index_max) - pattern_width):
    temp = index_max[i:i + pattern_width]
    s = set(temp)
    if len(s) == 1:
        final_list.append(temp[0])

print(final_list) # Output [5, 16, 34, 42]

工作示例https://ideone.com/Rz2gbK

答案 2 :(得分:1)

试试这个:

b

答案 3 :(得分:0)

如果列表始终排序,则只需count每个值:

final_list = [candidate for candidate in set(index_max) if index_max.count(candidate) >= pattern_width]

由于大多数呼叫是内置的,因此应该足够快。

如果您需要实际的窗口,请对您的方法进行两处修改:

  1. 在结束前仅迭代到pattern_width位置。
  2. 使用set标识唯一窗口。

    # stop iteration ``pattern_width`` elements before the end
    for i in range(len(index_max) - pattern_width):
      # slice the window from the list and eliminate duplicates
      window_elements = set(index_max[i:i+pattern_width])
      if len(window_elements) == 1:
        final_list.extend(window_elements)
    

答案 4 :(得分:0)

这是一个使用itertools的一堆方法的解决方案。我继续将问题分解为3个部分,这样如果你需要用代码做其他事情那么它就更灵活了。

import itertools
index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]
n = 4

def all_equal(iterable):
    g = itertools.groupby(iterable)
    return next(g, True) and not next(g, False)

def window(iterable, window_size):
    iters = itertools.tee(iterable, window_size)
    for i in range(1, window_size):
        for it in iters[i:]:
            next(it, None)
    return zip(*iters)

def uniques_from_window(iterable, window_size):
    return [sub_list[0] for sub_list in window(iterable, window_size) if all_equal(sub_list)]

print(uniques_from_window(index_max, n))

输出

[5, 16, 34, 42]