Identify groups of continuous numbers from consecutive list in python

徘徊边缘 提交于 2021-02-04 19:17:49

问题


What is the most efficient way in python for picking multiple n consecutive integers from n consecutive list, picking up one integer from each list. Here n is quite large..say in the order of 100s.

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

I'd like to print out the ranges of consecutive integers from consecutive lists, where first element is picked up from first list, second element from second list and so on and so forth:

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

回答1:


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



回答2:


I'd try sorting the lists first, using an efficient sorting algorithm. You can try Bubble Sort but other sorting algorithms might work as well.

You can then run through the integer from 1-n and look for continuous ranges of integer in the string. This way you have a maximum of n² operations for the sorting and n operations for the "finding".

Is this fast enough for you?




回答3:


You can use list comprehensions:

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]]

The gust of it is, for every number in the first list generate a sequence of incremented numbers and check if each one is contained in the corresponding list in the sequence of remaining lists.

Note that all stops iterating over the generator expression as soon as a condition is not satisfied, improving the efficiency of the method.

For a LARGE instance of the problem, it may be worth to convert all the lists to sets before the list comprehension, ls = [set(l) for l in ls]


Addendum

A variation w/o list comprehension using a for loop and a conditional statement, note that the inner lists were converted to sets before the search for sequences.

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)))



回答4:


Maybe using sets will be fast enough for your application? Is a bit brute force-y, but if I understood correctly, it is compliant with your restrictions:

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


来源:https://stackoverflow.com/questions/36976419/identify-groups-of-continuous-numbers-from-consecutive-list-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!