简体   繁体   中英

Python: How to convert a list of integers into nested lists of integers where max-min for each nested list never exceeds X?

I'm actually having a hard time explaining this problem. The title ask for this:

limit = 100
l = [1, 2, 4, 9, 33, 77, 85, 100, 151, 304, 405, 407, 499]

do_something(l, limit)

[
[1,2,4,9,33,77,85,100],
[151],
[304],
[405, 407, 499]
]

But that was just one step in my thought process. Truth is, I need this result:

limit = 100
l = [1, 2, 4, 9, 33, 77, 85, 100, 151, 304, 405, 407, 499]

do_something(l, limit)

[
range(1,101),
range(151,152),
range(304,305),
range(405,500)
]

Notice range never exceeds the limit of 100, and its creating a list out of ints from l that fall within the limit (starting from l[0] and resetting any time limit is exceeded). I am brainstorming ideas over here, but everything I can think of iterates over my list several times. If that's necessary so be it, but I'd like to be a bit more efficient than that.

Thanks for any help

Loop through the sorted list. Each time you start a group, save the first value of the range in one variable. Then as you step through the list, update the last value of the range to the current element. Whenever the element exceeds first+limit , you start a new range.

def do_something(l, limit):
    if l == []:
        return []
    end = l[0] + limit
    result = []
    first = last = l[0]
    for i in sorted(l):
        if i < end:
            last = i
        else:
            result.append(range(first, last + 1))
            first = last = i
            # reset the limit
            end = i + limit
    # append the last sublist
    result.append(range(first, last+1))
    return result

you also can emplement such logic:

def do_something(l,limit):
    res = []
    x = y = 0
    for y in range(len(l)):
        if y==len(l)-1 or l[x] + limit <= l[y+1]:
            res.append(range(l[x], l[y]+1))
            x = y + 1
    return res

do_something(l,limit)

>>> out
'''
[range(1, 101), range(151, 152), range(304, 305), range(405, 500)]

Why dont you try dictionaries to store list of values within limit. In this implementation, list is not necessarily to be sorted.

limit = 100
ranged_list = {}
for col in l:
  lst = ranged_list.get((col-1) // limit, [])
  lst.append(col)
  ranged_list[(col-1) // limit] = lst

print(list(ranged_list.values()))

>>> [
[1, 2, 4, 9, 33, 77, 85,100], 
[151],
[304],
[405, 407, 499]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM