# Go 中的随机排列数组

##### 问题描述投票：0回答：7

``````import random

list = [i for i in range(1, 25)]
random.shuffle(list)
print(list)
``````

arrays go
##### 7个回答
122

dystroy 的答案是完全合理的，但也可以在不分配任何额外切片的情况下进行洗牌。

``````for i := range slice {
j := rand.Intn(i + 1)
slice[i], slice[j] = slice[j], slice[i]
}
``````

``rand.Perm``

106

``````list := rand.Perm(25)
for i, _ := range list {
list[i]++
}
``````

``rand.Perm``

``````dest := make([]int, len(src))
perm := rand.Perm(len(src))
for i, v := range perm {
dest[v] = src[i]
}
``````

79

Go 1.20（2022 年第 4 季度）：正如我在“如何正确播种随机数生成器”中提到的，您不再需要

``rand.Seed()``

2017：从 1.10 开始，Go 包含官方的 Fisher-Yates shuffle 函数。

``pkg/math/rand/#Shuffle``

## 数学/兰特：添加随机播放

Shuffle 使用 Fisher-Yates 算法。

``Int31n``

``BenchmarkPerm30ViaShuffle``

``BenchmarkPerm30``

``rand.Seed(time.Now().UnixNano())``

``````words := strings.Fields("ink runs from the corners of my mouth")
rand.Shuffle(len(words), func(i, j int) {
words[i], words[j] = words[j], words[i]
})
fmt.Println(words)
``````

10

Evan Shaw的回答有一个小错误。如果我们从最低索引到最高索引迭代切片，以获得均匀（伪）随机洗牌，根据同一篇文章，我们必须从区间

``[i,n)``

``[0,n+1)``

``rand.Intn()``
，我们可以这样做：

``````    for i := len(slice) - 1; i > 0; i-- {
j := rand.Intn(i + 1)
slice[i], slice[j] = slice[j], slice[i]
}
``````

4

``````func main() {
slice := []int{10, 12, 14, 16, 18, 20}
Shuffle(slice)
fmt.Println(slice)
}

func Shuffle(slice []int) {
r := rand.New(rand.NewSource(time.Now().Unix()))
for n := len(slice); n > 0; n-- {
randIndex := r.Intn(n)
slice[n-1], slice[randIndex] = slice[randIndex], slice[n-1]
}
}
``````

1

``math/rand``

``````// Random numbers are generated by a Source. Top-level functions, such as
// Float64 and Int, use a default shared Source that produces a deterministic
// sequence of values each time a program is run. Use the Seed function to
// initialize the default Source if different behavior is required for each run.
``````

``Shuffle``

``````import (
"math/rand"
)

func Shuffle(array []interface{}, source rand.Source) {
random := rand.New(source)
for i := len(array) - 1; i > 0; i-- {
j := random.Intn(i + 1)
array[i], array[j] = array[j], array[i]
}
}
``````

``````source := rand.NewSource(time.Now().UnixNano())
array := []interface{}{"a", "b", "c"}

Shuffle(array, source) // [c b a]
``````

1

Raed 的方法 非常不灵活，因为

``[]interface{}``

``````func Shuffle(slice interface{}) {
rv := reflect.ValueOf(slice)
swap := reflect.Swapper(slice)
length := rv.Len()
for i := length - 1; i > 0; i-- {
j := rand.Intn(i + 1)
swap(i, j)
}
}
``````

``````    rand.Seed(time.Now().UnixNano()) // do it once during app initialization
s := []int{1, 2, 3, 4, 5}
Shuffle(s)
fmt.Println(s) // Example output: [4 3 2 1 5]
``````