从 python 中的连续列表中识别连续数字组

Identify groups of continuous numbers from consecutive list in python

python 中从 n 个连续列表中选取多个 n 个连续整数的最有效方法是什么,从每个列表中选取一个整数。这里的 n 很大.. 大约 100s.

L1 = [5,3,2,7,1]
L2 = [3,5,6,8,9,21,2]
L3 = [5,3,6,7,3,9]

我想打印出连续列表中连续整数的范围,其中第一个元素从第一个列表中选取,第二个元素从第二个列表中选取,依此类推:

Candidate solution [5,6,7], [1,2,3], [7,8,9]

我会先尝试使用高效的排序算法对列表进行排序。您可以尝试 Bubble Sort 但其他排序算法也可能有效。

然后您可以 运行 通过 1-n 中的整数并在字符串中查找连续的整数范围。这样,您最多可以进行 n² 次排序操作和 n 次 "finding" 操作。

这对你来说够快吗?

L1 = [5,3,2,7,1]
L2 = [3,5,6,8,9,21,2]
L3 = [5,3,6,7,3,9]
cons_l = []
L = [L2] + [L3] #+[L4] #+ ...+ ..... ### Add any number of list here..

j = 0
for l1 in L1:
   cons_l.append([])
   cons_l[j].append(l1)
   for l in range(0, len(L)):
      if l1+l+1 in L[l]:
         cons_l[j].append(l1+l+1)
      else:
         del cons_l[j]
         j -= 1
         break
   j += 1
print cons_l

也许使用集合对您的应用程序来说足够快了?有点暴力,但如果我理解正确,它符合您的限制:

lists = [
  [5,3,2,7,1],
  [3,5,6,8,9,21,2],
  [5,3,6,7,3,9],
]

candidates = list()

# Without the first one
rest_of_sets = [set(l) for l in lists[1:]]

for fe in lists[0]:
    skip_partial = False
    for i, s in enumerate(rest_of_sets, 1):
        if fe + i not in s:
            skip_partial = True
            break
    if not skip_partial:
        candidates.append(range(fe, fe+len(sets)))

print candidates

您可以使用列表理解:

In [23]: ls = [[5,3,2,7,1],[3,5,6,8,9,21,2],[5,3,6,7,3,9],]

In [24]: l = len(ls)

In [25]: [list(range(s,s+l)) for s in ls[0] if all(i in l for i,l in zip(range(s+1,s+l),ls[1:]))]
Out[25]: [[5, 6, 7], [7, 8, 9], [1, 2, 3]]

它的意思是,对于第一个列表中的每个数字生成一个递增数字序列,并检查每个数字是否包含在剩余列表序列中的相应列表中。

请注意,一旦条件不满足,all 就会停止迭代生成器表达式,从而提高该方法的效率。

对于问题的大型实例,在列表理解之前将所有列表转换为集合可能是值得的,ls = [set(l) for l in ls]


附录

使用 for 循环和条件语句的变体 w/o 列表理解,请注意,在搜索序列之前,内部列表已转换为集合。

ls = [[5, 3, 2, 7, 1], [3, 5, 6, 8, 9, 21, 2], [5, 3, 6, 7, 3, 9]]
l = len(ls)
ls = [set(li) for li in ls]

candidates = []
for n in ls[0]:
    if all(i in l for i, l in zip(range(n+1, n+l), ls[1:])):
        candidates.append(list(range(n, n+l)))