Home > Enterprise >  Sum of element and next element with condition python
Sum of element and next element with condition python

Time:10-06

I have a script that generates a randomised list of numbers between 0,60 and it is sorted in ascending order.

Essentially, I want to check if the difference between each element, and the element next to it is above 3, and if it is not, I want the list to be regenerated until the condition applies.

For example:

my_list = [1, 2, 3, 4, 5]
# this would not pass

my_list = [1, 5, 9, 13, 20]
# this would pass as the difference between each element and the next is more than 3

My code so far:

def generateList():
    timeSlots = list(range(0, 60)) # generate random list
    random.shuffle(timeSlots) # shuffle list

    timeSlots = timeSlots[:9] # shorten list to 9 elements
    timeSlots.sort() # sort list in ascending order

    for cur, nxt in zip(timeSlots, timeSlots[1:]):
        diff = (nxt - cur) # check difference
        if diff < 3:
            # HELP HERE
            # regenerate timeSlots until the sum of each element and the next element is bigger than 3
     
    return timeSlots

CodePudding user response:

You want to use all():

def generateList():
    while True:
        timeSlots = list(range(0, 60)) # generate random list
        random.shuffle(timeSlots) # shuffle list

        timeSlots = timeSlots[:9] # shorten list to 9 elements
        timeSlots.sort() # sort list in ascending order
        if all(nxt - cur > 3 for cur, nxt in zip(timeSlots, timeSlots[1:])):
            return timeSlots

Note, if you want to select only 9 elements, then you can use randome.sample().

import random
def generate_list():
    while True:
        time_slots = random.sample(range(60), 9) # note this will not include 60 in the population
        time_slots.sort() # sort list in ascending order

        # or combine the above 2 lines as
        # time_slots = sorted(random.sample(range(60), 9))

        if all(nxt - cur > 3 for cur, nxt in zip(time_slots, time_slots[1:])):
            return time_slots

CodePudding user response:

You can just perform a recursive call if your list does not match your criteria. This add a single line to your program:

import random

def generateList():
    timeSlots = list(range(0, 60))
    random.shuffle(timeSlots)

    timeSlots = timeSlots[:9]
    timeSlots.sort()

    for cur, nxt in zip(timeSlots, timeSlots[1:]):
        diff = (nxt - cur)
        if diff < 3:
            return generateList()  #  does not work => try a new one
    return timeSlots

generateList()

CodePudding user response:

import random
def generateList():
    while True:
        timeSlots = list(range(0, 60))  # generate random list
        random.shuffle(timeSlots)  # shuffle list
        timeSlots = timeSlots[:9]  # shorten list to 9 elements
        timeSlots.sort()  # sort list in ascending order

        for cur, nxt in zip(timeSlots, timeSlots[1:]):
          diff = (nxt - cur)  # check difference
          if diff < 3:
              break
        else:
            return timeSlots


print(generateList())

CodePudding user response:

I want to check if the difference between each element, and the element next to it is above 3, and if it is not, I want the list to be regenerated until the condition applies.

Answers have already shown how to check the list, but depending on your numbers, the chances for generating a valid list of that kind might be very low, or there might not be a valid list at all. In this case, your loop would run a long time, or infinitely.

Instead, you can just generate a valid list. Let's say the K=10 elements must be smaller than N=60 with a difference greater than M=3. Then you know that M*(K-1) has to be "reserved" for the gaps, and you can random.sample numbers from the rest, then apply the accumulated gaps afterwards.

import random

N, M, K = 60, 3, 10

nums = sorted(random.sample(range(N - (K-1)*M), K))
# [2, 5, 13, 16, 21, 23, 27, 28, 31, 32]  (random)

res = [x   i*M for i, x in enumerate(nums)]
# [2, 8, 19, 25, 33, 38, 45, 49, 55, 59]  (random)

As a side effect, this will immediately raise an exception if there is no such list.

Thus, your generateList function could look like this, without loops:

def generateList(n=60, m=3, k=10):
    nums = sorted(random.sample(range(n - (k-1)*m), k))
    return [x   i*m for i, x in enumerate(nums)]
  • Related