I have some tuple in python. And capacity limit, for example, is 5. I want to split tuple in subtuples limited by sum of them elements:
For example:
input: (3, 1, 4, 2, 2, 1, 1, 2) and capacity = 5
output: (3, 1) (4) (2, 2, 1) (1, 2) #each subtuple is less than 5, order safe.
I am looking for a nice expressive solution of this task preferable in functional style of programming (using itertools.dropwhile
for example or something like that)
In order to split it in four sub-tuple of three elements each, slice a tuple of three successive elements from it and append the segment in a lis. The result will be a list of 4 tuples each with 3 numbers.
To split a tuple, just list the variable names separated by commas on the left-hand side of an equals sign, and then a tuple on the right-hand side.
We can do that by using a tuple containing two or more elements. A tuple is an ordered set of one or more elements, which can have different types.
A tuple can have any number of items and they may be of different types (integer, float, list, string, etc.). A tuple can also be created without using parentheses. This is known as tuple packing. Creating a tuple with one element is a bit tricky.
How to split Python tuples into sub-tuples? Here is a tuple with 12 integers. In order to split it in four sub-tuple of three elements each, slice a tuple of three successive elements from it and append the segment in a lis. The result will be a list of 4 tuples each with 3 numbers.
Note: In all the cases above, max split = -1, which means there is no limit on the number of splits. Split () function with optional parameter ‘max splits’.
Python has two built-in methods that you can use on tuples. Method Description count() Returns the number of times a specified value occurs in a tuple index() Searches the tuple for a specified value and returns the position of where it was found ❮ PreviousNext ❯
You can unpack tuples with variable names separated by commas. To split a tuple, just list the variable names separated by commas on the left-hand side of an equals sign, and then a tuple on the right-hand side. Below is an example of splitting a tuple into three variables in Python.
You could encapsulate non-functional part and call it from functional code:
from itertools import groupby
class GroupBySum:
def __init__(self, maxsum):
self.maxsum = maxsum
self.index = 0
self.sum = 0
def __call__(self, value):
self.sum += value
if self.sum > self.maxsum:
self.index += 1
self.sum = value
return self.index
# Example:
for _, l in groupby((3, 1, 4, 2, 2, 1, 1, 2), GroupBySum(5)):
print(list(l))
I couldn't help it but write something close to what I'd do in Haskell (while still somewhat pythonic, I think):
def take_summed(xs, cap):
if len(xs) <= 1:
return xs, ()
else:
x, *rest = xs
if x > cap:
return (), xs
else:
init, tail = take_summed(rest, cap - x)
return (x,) + tuple(init), tail
def split(xs, cap=5):
if len(xs) <= 1:
yield xs
else:
chunk, rest = take_summed(xs, cap)
yield chunk
if rest != ():
yield from split(rest, cap)
Never hesitate to split functions into subproblems. Result:
In [45]: list(split((3, 1, 4, 2, 2, 1, 1, 2), 5))
Out[45]: [(3, 1), (4,), (2, 2, 1), (1, 2)]
The problem with making this shorter is not that it's not doable without side effects, but that you have to carry around additional accumulated state, so even when using reduce
you would need to invent something really complex, to pass around the sum between applications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With