Two separate lists with corresponding numbers. How to detect them remove them from the list?
<p>I'm looking to create a program which randomly generates coins on an 8x8 grid.  I've got two lists being created (one list for the X co-ordinate and list for the Y co-ordinate).  On these lists, the two co-ordinates cannot be the same.  It's difficult to explain, so here's what I mean by example:</p>

<pre><code>[1, 7, 4, **6**, 9, 2, 3, **6**, 8, 0] (list for the x co-ordinate)
[9, 3, 3, **1**, 2, 8, 0, **1**, 6, 1] (list for the y co-ordinate)
</code></pre>

<p>So, two lists are created. However <code>(6,1)</code> appears twice.  I don't want this.  So, how would I allow for this in my code, to ensure that this is ignored and the numbers are regenerated into different co-ordinates?  The code I have is below, I don't really know how to implement such a system thing!  </p>

<pre><code>def treasurePro():
    global coinListX, coinListY
    coinListX = []
    coinListY = [] 
    for x in range(10): 
        num = randint(0,8) 
        coinListX.append(num) 
        print(coinListX)
    for x in range(10): 
        num = randint(0,8)
        if num == 0 and coinListX[x] == 0:
            treasurePro() #goes back to the beginning to restart.  
        else:
            coinListY.append(num) 
            print(coinListY)
</code></pre>

<p>Don't create two lists with coordinates, at least not initially. That only makes it harder to detect duplicates.</p>

<p>You could either create <em>tuples</em> with coordinates so you can detect duplicates, or even produce a range of integers that represent your coordinates in sequence, then sample from those. The latter is extremely efficient.</p>

<p>To create tuples, essentially you want to create 8 unique such tuples:</p>

<pre><code>def treasurePro():
    coords = []
    while len(coords) &lt; 8:
        coord = randint(0, 8), randint(0, 8)
        if coord not in coords:
            coords.append(coord)
    # now you have 8 unique pairs. split them out
    coinListX, coinListY = zip(*coords)
</code></pre>

<p>This isn't all that efficient, as the <code>coord not in coords</code> test has to scan the whole list which is growing with each new coordinate. For a large number of coordinates to pick, this can slow down significantly. You'd have to add an extra <code>seen = set()</code> object that you also add coordinates to and test again in the loop to remedy that. There is a better way however.</p>

<p>Your board is a 9x9 size, so you have 81 unique coordinates. If you used <a href="https://docs.python.org/3/library/random.html#random.sample" rel="nofollow"><code>random.sample()</code></a> on a <a href="https://docs.python.org/3/library/stdtypes.html#ranges" rel="nofollow"><code>range()</code> object</a> (<code>xrange()</code> in Python 2), you could trivially create 8 unique values, then 'extract' a row and column number from those:</p>

<pre><code>def treasurePro():
    coords = random.sample(range(9 * 9), 8)  # use xrange in Python 2
    coinListX = [c // 9 for c in coords]
    coinListY = [c % 9 for c in coords]
</code></pre>

<p>Here <code>random.sample()</code> guarantees that you get 8 unique coordinates.</p>

<p>This is also far more efficient than generating all possible tuples up-front; using <code>range()</code> in Python 3 makes the above use O(K) memory, where K is the number of values you need to generate, while creating all coordinates up front would take O(N^2) memory (where N is the size of a board side).</p>

<p>You may want to store a list of <code>(x, y)</code> coordinates still rather than use two separate lists. Create one with <code>coords = [(c // 9, c % 9) for c in coords]</code>.</p>

python arrays list python-3.x