所以我假设我有以下列表
F = ["A","B","C","D","E"]
现在我想要洗牌这个列表中的元素,但只是从B到E的人.A应该始终保持在开头。剩下的应该是shuffeld。
之后,我想将一些列表放在一起,例如:
FA = [["A1","B1","B2","B3"]["A2","B2","B3","B4"]...]
如果这样做,我将选择其中一个列表,并且应该洗牌元素(“A”除外)。
无法提出解决方案...... :(
答案 0 :(得分:2)
使用random.shuffle()
source code:
from random import randrange
def random_shuffle(x, fixed_indexes):
for i in reversed(range(1, len(x))): # from random.shuffle() source code
if i not in fixed_indexes:
# pick an element in x[:i+1] with which to exchange x[i]
while True:
j = randrange(i+1)
if j not in fixed_indexes:
break
# swap
x[i], x[j] = x[j], x[i]
示例:
>>> F = ["A", "B", "C", "D", "E"]
>>> random_shuffle(F, set([0]))
>>> F
['A', 'E', 'C', 'B', 'D']
答案 1 :(得分:1)
我们基本上将索引洗牌而不是改组值:
import random
def shuffle_except(lst, keep):
# keep should be a list of the indexes that we want to keep fixed
# can also be a range or a sum of range
# keep = range(0, 2) + range(5, 8)
keep = set(keep)
start_indexes = [i for i in xrange(len(lst)) if i not in keep]
end_indexes = [i for i in xrange(len(lst)) if i not in keep]
# we shuffle end indexes
random.shuffle(end_indexes)
# for each element in start_indexes, we move the corresponding element of lst
# to its counterpart in end_indexes
for i in xrange(len(start_indexes)):
start = start_indexes[i]
end = end_indexes[i]
lst[start], lst[end] = lst[end], lst[start]
a = range(20)
print a
print a[1], a[5], a[10], a[15]
shuffle_except(a, {1, 5, 10, 15})
print a
print a[1], a[5], a[10], a[15]
打印:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
1 5 10 15
[7, 1, 3, 2, 9, 5, 13, 0, 16, 8, 10, 11, 18, 17, 12, 15, 4, 6, 14, 19]
1 5 10 15
正如您所看到的,除了我们指定的元素之外,现在所有元素都被洗牌了。
现在,如果你也想要多次洗牌,这里有一个例子:
multi_list = [range(10) for _ in xrange(5)]
keep = {0, 3, 5}
for lst in multi_list:
shuffle_except(lst, keep)
print multi_list
结果如下:
[
[0, 6, 2, 3, 4, 5, 1, 7, 8, 9],
[0, 4, 2, 3, 1, 5, 7, 9, 6, 8],
[0, 1, 4, 3, 2, 5, 8, 6, 7, 9],
[0, 2, 7, 3, 1, 5, 9, 4, 6, 8],
[0, 6, 4, 3, 1, 5, 2, 9, 7, 8]
]
同样,您可以看到列0,3和5始终具有与原始列表中相同的确切值