Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split python tuple in subtuples with capacity limit in functional programming style

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)

like image 332
Evg Avatar asked Oct 30 '16 16:10

Evg


People also ask

Can we use split function in tuple?

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.

How do you split a tuple element in Python?

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.

Can a tuple have more than 2 elements?

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.

How many items can a tuple hold?

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?

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.

What is the maximum number of splits in Python?

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’.

How to count the number of times a tuple occurs in Python?

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 ❯

How do you unpack a tuple with three variables in Python?

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.


2 Answers

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))
like image 64
GingerPlusPlus Avatar answered Sep 20 '22 16:09

GingerPlusPlus


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.

like image 42
phipsgabler Avatar answered Sep 18 '22 16:09

phipsgabler