f = open(raw_input("File")).read().split()
cows = f[0]
data = dict(enumerate(f[1:],start=1))
print data
nonloopy = []
loopy = []
def isloopy(cownum,data,did=[]):
    print "   ",cownum,did
    cownum = int(cownum)
    if cownum in nonloopy:
        return False
    elif cownum in loopy:
        return True
    if cownum in did:
        return True
    if cownum == 0:
        return False
    did.append(cownum)
    nextcownum = data[cownum]
    isloopy(nextcownum,data,did)
for i in data:
    value = data[i]
    print i,value,nonloopy,loopy
    if isloopy(i,data):
        loopy.append(i)
        print"   ","Loopy"
    else:
        nonloopy.append(i)
        print"   ","Non-loopy"

The instructions are here
The output is this:

File1.in
{1: '0', 2: '4', 3: '1', 4: '5', 5: '4'}
1 0 [] []
    1 []
    0 [1]
    Non-loopy
2 4 [1] []
    2 [1]
    4 [1, 2]
    5 [1, 2, 4]
    4 [1, 2, 4, 5]
    Non-loopy
3 1 [1, 2] []
    3 [1, 2, 4, 5]
    1 [1, 2, 4, 5, 3]
    Non-loopy
4 5 [1, 2, 3] []
    4 [1, 2, 4, 5, 3]
    Loopy
5 4 [1, 2, 3] [4]
    5 [1, 2, 4, 5, 3]
    Loopy
4

The problem is keyword arguments are changing.
But, If I change line 7(def isloopy(cownum,data,did=[]):) to def isloopy(cownum,data,did=None):
and add

if did == None:
    did = []

I get:

{1: '0', 2: '4', 3: '1', 4: '5', 5: '4'}
1 0 [] []
    1 []
    0 [1]
    Non-loopy
2 4 [1] []
    2 []
    4 [2]
    5 [2, 4]
    4 [2, 4, 5]
    Non-loopy
3 1 [1, 2] []
    3 []
    1 [3]
    Non-loopy
4 5 [1, 2, 3] []
    4 []
    5 [4]
    4 [4, 5]
    Non-loopy
5 4 [1, 2, 3, 4] []
    5 []
    4 [5]
    Non-loopy
6

P.S. Icouldn't upload the python file or the problem data!

Edited 3 Years Ago by Gribouillis: corrected link

You must not use directly use list for parameter default but use None as default:

f = open("relay.in").read().split()
cows = f[0]
data = dict(enumerate(f[1:],start=1))
print data
nonloopy = []
loopy = []

def isloopy(cownum,data,did=None):
    if did == None:
        did=[]
    print "   ",cownum,did
    cownum = int(cownum)
    if cownum in nonloopy:
        return False
    elif cownum in loopy:
        return True
    if cownum in did:
        return True
    if cownum == 0:
        return False
    did.append(cownum)
    nextcownum = data[cownum]
    isloopy(nextcownum,data,did)

for i in data:
    value = data[i]
    print i,value,nonloopy,loopy
    if isloopy(i,data):
        loopy.append(i)
        print"   ","Loopy"
    else:
        nonloopy.append(i)
        print"   ","Non-loopy"

For starters, your recursive call has no exit point so could easily go beyond the length of the list

    isloopy(nextcownum,data,did)

This doesn't happen because the
1: '0', 2: '4', 3: '1'
is a repetitive loop if I read this correctly (3 goes back to 1), so

    if cownum in did:
        return True

is executed. Add some print statements to show what is being processed and the contents of the lists. As I said, I am not sure I understand what you are trying to do, but think you want to return the result of the recursive call instead of "None" which is what is being returned now.

    return isloopy(nextcownum,data,did)
    ## Not
    isloopy(nextcownum,data,did)

Again, print statements will help tell what is happening.

Edited 3 Years Ago by woooee

This article has been dead for over six months. Start a new discussion instead.