0

python newbie here.

I am working my way towards a recursive, memoized (on a formula of two variables) function but I'm currently a ways away.

So currently I think my main problem is that after I call the function, fun1 initially, and do some manipulation, I then want to pass an altered group of initial agruments to the function again. But when I do that the error says it receives just one argument - a tuple. Here is the error and the script at the bottom. Currently I am just trying to remove one argument at a time (p1tpn) until there is only one left, but the real case will be different.

fun1(2,4,6)

I was called with 3 arguments: (2, 4, 6)
with arg <class 'tuple'>
[arg] is type: <class 'list'>
list on arg [2, 4, 6] and is type: <class 'list'>
argList is: [2, 4, 6]

[[2, 4], [6]]

first arg is: 2
rest of arg is: [4, 6]
I was called with 1 arguments: ([4, 6],)
with arg <class 'tuple'>
[arg] is type: <class 'list'>
list on arg [[4, 6]] and is type: <class 'list'>
argList is: [[4, 6]]

[[[4, 6]]]

first arg is: [4, 6]
rest of arg is: []

So I see that near the completion of the first call, with rest of arg is [4, 6], upon entering the second "call/instantiation" it says this is 1 argument. I guess the other things could have been taken out (memoize) but one can see they are not being implemented yet.

def partition(collection):
    if len(collection) == 1:
        yield [ collection ]
        return

    first = collection[0]
    for smaller in partition(collection[1:]):
        # insert `first` in each of the subpartition's subsets
        for n, subset in enumerate(smaller):
            yield smaller[:n] + [[ first ] + subset]  + smaller[n+1:]
        # put `first` in its own subset 
        yield [ [ first ] ] + smaller

def memoize(f):
    memo = {}
    def helper(x):
        if x not in memo:
            memo[x] = f(x)
        return memo[x]
    return helper

fun1 = memoize(fun1)

def fun1(*arg):
    lArg = len(arg)
    firstNumber = arg[0]
    print("I was called with", len(arg), "arguments:", arg)
    print("with arg", type(arg))
    argList = list(arg)
    print("argList is:",argList)
    print("first arg is:", arg[0])
    p1tpn = argList[1:]
    print("rest of arg is:", p1tpn)
#
    if firstNumber == 1 : return 1
    else: fun1(p1tpn)

The partition function definition I got from Set partitions in Python

1
  • it’s one arg cus it’s a list so it will always be one Commented Jan 20, 2018 at 20:59

1 Answer 1

1

The def fun1(*args) (note that this is the function definition) syntax packs any number of passed in arguments into a list. In your recursive call you are indeed passing in just a single argument, the list itself. You'll want to modify the recursive call to un pack the list of arguments for the function call fun1(*p1tpn)

Here's some more info on the semantics of the * and ** operators What does ** (double star/asterisk) and * (star/asterisk) do for parameters?

Also, as a side note you can use the built-in lru_cache for the memoization:

https://docs.python.org/3/library/functools.html#functools.lru_cache

Sign up to request clarification or add additional context in comments.

2 Comments

Aahhh I didn't know what the operation was called... with "packing" I quickly found: stackoverflow.com/questions/12786102/… I will spend some time looking over your links.
yeah, so the problem is that it does both "packing" and "unpacking" depending on where it's used, in function calls it unpacks lists, but in function definitions it (kind of) packs arguments into tuples

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.