<p>Here is an approach based on <a href="https://arxiv.org/pdf/1309.3873.pdf" rel="noreferrer">this paper</a> which proves a result about the mixing time needed to scramble a list by using swaps of adjacent items</p>

<pre><code>from random import choice
from math import log

def jitter(items,percent):
    n = len(items)
    m = (n**2 * log(n))
    items = items[:]
    indices = list(range(n-1))
    for i in range(int(percent*m)):
        j = choice(indices)
        items[j],items[j+1] = items[j+1],items[j]
    return items
</code></pre>

<p>A test, each line showing the result of <code>jitter</code> with various percents being applied to the same list:</p>

<pre><code>ls = list(('0'*20 + '1'*20)*2)

for i in range(11):
    p = i/10.0
    print(''.join(jitter(ls,p)))
</code></pre>

<p>Typical output:</p>

<pre><code>00000000000000000000111111111111111111110000000000000000000011111111111111111111
00000000000000111100001101111011011111001010000100010001101000110110111111111111
00000000100100000101111110000110111101000001110001101001010101100011111111111110
00000001010010011011000100111010101100001111011100100000111010110111011001011111
00100001100000001101010000011010011011111011001100000111011011111011010101011101
00000000011101000110000110000010011001010110011111100100111101111011101100111110
00110000000001011001000010110011111101001111001001100101010011010111111011101100
01101100000100100110000011011000001101111111010100000100000110111011110011011111
01100010110100010100010100011000000001000101100011111011111011111011010100011111
10011100101000100010001100100000100111001111011011000100101101101010101101011111
10000000001000111101101011000011010010110011010101110011010100101101011110101110
</code></pre>

<p>I'm not sure how principled the above is, but it seems like a reasonable place to start.</p>
varying degree of shuffling using random module python
<p>I am using two architecture programs, with visual programming plugins (Grasshopper for Rhino and Dynamo for Revit - for those that know / are interested) </p>

<p>Grasshopper contains a function called 'Jitter' this will shuffle a list, however it has an input from 0.0 to 1.0 which controls the degree of shuffling - 0.0 results in no shuffling 1.0 produces a complete shuffle. </p>

<p>The second of the programs (Dynamo) does not contain this functionality. It contains a shuffle module (which contains a seed value) however it is a complete random shuffle. </p>

<p>Ultimately the goal is to produce a series of solid and glazed panels, but to produce a slight random effect (but avoiding large clumping of solid and glazed elements - hence I want a "light shuffle")</p>

<p>I have written a code which will calculate the number of glazed(True) and solid(False) values required and then evenly distribute True and False values based on the number of items and percent specified.</p>

<p>I have checked out the random module reference however I'm not familiar with the various distributions as described. </p>

<p>Could someone help out or point me in the right direction if an existing function would achieve this. </p>

<p>(I have cheated slightly by adding True False alternately to make up the correct number of items within the list - list3 is the final list, list2 contains the repeated module of true falses) </p>

<p>Many thanks </p>

<pre><code>import math
import random

percent = 30
items = 42

def remainder():
    remain = items % len(list2)

    list3.append(True)
    remain -= 1

    while remain &gt; 0 :
        list3.append(False)
        remain -= 1

    return list3

#find module of repeating True and False values
list1 = ([True] + [False] * int((100/percent)-1))

#multiply this list to nearest multiple based on len(items)
list2 = list1 * int(items/(100/percent))

# make a copy of list2
list3 = list2[:]

#add alternating true and false to match len(list3) to len(items)
remainder()

#an example of a completely shuffled list - which is not desired 
shuffled = random.sample(list3, k = len(list3))
</code></pre>