Mason Gardner
Mason Gardner

Reputation: 311

Creation of unexpected tuple value

I am dealing with somewhat of a mystery and hoped for some clarity. I wrote a script for finding dice roll combinations adding to 24 that looks like the following:

start=[3,3,3,3,3,3,3,3]
outcomes=set(tuple(start)) #Use a set to ensure uniqueness

index_list=np.random.randint(0,8,1000)

#This little snippet adds one and subtracts one randomly, keeping total at 24
for i in xrange(0,500):
    upper=index_list[i]
    downer=index_list[i+20]

    if start[upper]!=6 and start[downer]!=1:
        start[upper]=start[upper]+1
        start[downer]=start[downer]-1
        outcomes.add(tuple(start))

print outcomes

What I am running into, is that When I look at outcomes, there is a single 3 of type 'int' in there.

set([(4, 4, 4, 3, 2, 2, 2, 3), 3, (2, 5, 4, 3, 1, 4, 2, 3), (4, 4, 4, 2, 3, 1, 3, 3),(4, 2, 5, 2, 3, 4, 1, 3)])

While I could certainly remove it, I am just curious how it is getting in there to begin with? My initial guess was the index list might be producing an index outside of [0-7], but it is not. I've looked for a similar question other places, but have yet to find a similar issue. Thanks!

Upvotes: 0

Views: 115

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140307

set expects an iterable. You're passing a tuple which is an iterable. set iterates through it, leaving just 1 value: 3 (because your tuple only contains the same 3 value).

You have to put your element in a list or tuple so it is seen as a single element (exactly the same problem when you pass a string and it is unexpectedly iterated upon)

The rest of your code is OK and has nothing to do with the problem.

Do this instead:

outcomes=set([tuple(start),])

now set iterates through a list of 1 tuple, effectively creating tuple elements.

You could do that also, maybe simpler:

outcomes=set()
outcomes.add(tuple(start))

there's no ambiguity since you're adding 1 element. It's not iterated through.

Upvotes: 1

Related Questions