So I wrote this code intended to let the code group different numbers from a list together in a total of n: int
groups
Edit If you do not understand what the purpose of the code is, please look in the comments, I've explained it there. Thank you:)
def calcdifference(lst: list):
for x in lst:
return (x -= x)
print(calcdifference(lst=[4,5,6,4,3,2,3,4,5]))
def grouping(lst: list, n: int):
if calcdifference(x) in list == max(calcdifference(x)):
lst.append(x)
print(grouping(lst=[4,5,6,4,3,2,3,4,5]))
n: int represents the number of groups permitted from one single list, so if n is 3, the numbers will be grouped in (x,...), (x,....) (x,...) If n = 2, the numbers will be grouped in (x,..),(x,...).
However, my code prints out all possible combinations in a list of n elements. But it doesnt group the numbers together. So what I want is: for instance if the input is
[10,12,45,47,91,98,99]
and if n = 2, the output would be
[10,12,45,47] [91,98,99]
and if n = 3, the output would be
[10,12] [45,47] [91,98,99]
What changes to my code should I make?
Note: please refrain from using built in functions or import since I want to use as less built in functions as possible
Important: the code should be able to print n >= len(lst)
combinations for every list provided
CodePudding user response:
You can try the following:
def grouping(lst, n):
diff = enumerate((abs(x - y) for x, y in zip(lst, lst[1:])), start=1)
cut = sorted(x[0] for x in sorted(diff, reverse=True, key=lambda x: x[1])[:n-1])
cut = [0, *cut, len(lst)] # add 0 and last index
return [lst[i:j] for i, j in zip(cut, cut[1:])] # return slices
lst = [10,12,45,47,91,98,99]
print(grouping(lst, 2))
print(grouping(lst, 3))
print(grouping(lst, 4))
Output:
[[10, 12, 45, 47], [91, 98, 99]]
[[10, 12], [45, 47], [91, 98, 99]]
[[10, 12], [45, 47], [91], [98, 99]]
Admittedly it is quite complicated and perhaps less pythonic. There might be a more efficient way. Anyways some explanation follows...
In the first line, diff
is a (sort of) list containing tuples (i, d)
such that lst
has difference of d
between i-1
th item and i
th item.
The second line is more complicated. First, sorted(diff, reverse=True, key=lambda x: x[1])
sorts those tuples according to the second element, i.e., the tuple representing highest jump comes first.
Then sorted(...)[:n-1]
picks the first n-1 tuples. Those will be the n-1 cuts to be used.
Generator comprehension (x[0] for x in ...)
just picks the first item of each tuples; i.e., we no longer need the differences.
And then again sorted(...)
will sort those cut positions, which will make the subsequent line work.
If you are reluctant to use lambda
for some reason (actually operator.itemgetter(1)
is better than lambda x: x[1]
), you can just make a custom function for that.
def get_1st(x):
return x[1]
def grouping(lst, n):
diff = enumerate((abs(x - y) for x, y in zip(lst, lst[1:])), start=1)
cut = sorted(x[0] for x in sorted(diff, reverse=True, key=get_1st)[:n-1])
cut = [0, *cut, len(lst)] # add 0 and last index
return [lst[i:j] for i, j in zip(cut, cut[1:])] # return slices