英文:
Generating multiple sets of decreasing numbers in python
问题
在Python中有办法生成多组随机生成但递减的数字吗?
例如,100个数字序列中的前十个数字应该从一个较大的数字开始递减,直到第十个。然后,接下来的十个数字将按相同的模式进行,从大到小递减,直到第二十个,依此类推。
这可能会看起来像这样:
1 100
2 84
3 66
4 63
5 41
6 35
7 30
8 18
9 9
10 8
11 98 # 下一个序列开始
12 55
13 54
14 33
15 22
16 11
17 8
18 7
19 5
20 2
理想情况下,可以为任何指定长度随机生成这些数字序列。
还可以通过生成具有随机长度的递减序列来提供额外的功能。
英文:
Is there a way to make multiple sets of randomly generated but decreasing numbers in python?
For example, the first ten numbers of a 100 number sequence should start with a large number and decrease until the tenth. Then, the next ten numbers will follow the same pattern, starting large and decreasing until the 20th, and so on.
This might look something like this:
1 100
2 84
3 66
4 63
5 41
6 35
7 30
8 18
9 9
10 8
11 98 # next sequence starts
12 55
13 54
14 33
15 22
16 11
17 8
18 7
19 5
20 2
Ideally, this could be randomly generated for any specified length.
Additional functionality could be provided by generating these decreasing sequences with random lengths.
答案1
得分: 1
Here is the translated content:
如果您希望所有数字都是不同的,也就是说,最多可以生成10组,这是一种方法:
import random
def gen_sets(n_sets):
if n_sets > 10:
raise ValueError("n_sets不能大于100")
l = list(range(1, 100))
random.shuffle(l)
for i in range(n_sets):
yield sorted(l[10*i:10*(i+1)], reverse=True)
my_sets = list(gen_sets(5))
-
range
用于生成100个整数。range文档 -
random.shuffle
用于打乱列表的元素。random shuffle文档 -
sorted
用于对每个集合进行排序,使用reverse=True
使其按降序排列。sorted文档
英文:
If you want all the numbers to be distinct, which means, at most you can generate 10 sets, here is a way to do it:
import random
def gen_sets(n_sets):
if n_sets>10:
raise ValueError("n_sets can't be bigger than 100")
l = list(range(1,100))
random.shuffle(l)
for i in range(n_sets):
yield sorted(l[10*i:10*(i+1)], reverse=True)
my_sets = list(gen_sets(5))
-
range
is used to generate the 100 integers. range doc -
random.shuffle
is used to shuffle the elements of the list. random shuffle doc -
sorted
is used to order each set, withreverse=True
to make it a decreasing order. sorted doc
答案2
得分: 1
I modified Seddik's code to make the function more parameterized.
import itertools
import random
def gen_random_sequences(limit, partitions):
max_partition_size = limit // 10
if partitions > max_partition_size:
raise ValueError(f'分区不能大于 {max_partition_size}')
available = list(range(1, limit + 1))
random.shuffle(available)
for partition in range(partitions):
yield sorted(available[10 * partition:10 * (partition + 1)], reverse=True)
sequences = list(gen_random_sequences(100, 2)) # 矩阵
print(sequences)
random_sequence = list(itertools.chain(*sequences)) # 扁平化矩阵
for i, n in enumerate(random_sequence):
print(f'{i + 1} {n}')
示例输出
[[95, 85, 76, 71, 49, 42, 39, 33, 16, 1], [100, 92, 77, 64, 63, 48, 41, 40, 18, 15]]
1 95
2 85
3 76
4 71
5 49
6 42
7 39
8 33
9 16
10 1
11 100
12 92
13 77
14 64
15 63
16 48
17 41
18 40
19 18
20 15
英文:
I modified Seddik's code to make the function more parameterized.
import itertools
import random
def gen_random_sequences(limit, partitions):
max_partition_size = limit // 10
if partitions > max_partition_size:
raise ValueError(f'Partitions can\'t be larger than {max_partition_size}')
available = list(range(1, limit + 1))
random.shuffle(available)
for partition in range(partitions):
yield sorted(available[10 * partition:10 * (partition + 1)], reverse=True)
sequences = list(gen_random_sequences(100, 2)) # Matrix
print(sequences)
random_sequence = list(itertools.chain(*sequences)) # Flatten matrix
for i, n in enumerate(random_sequence):
print(f'{i + 1} {n}')
Sample output
[[95, 85, 76, 71, 49, 42, 39, 33, 16, 1], [100, 92, 77, 64, 63, 48, 41, 40, 18, 15]]
1 95
2 85
3 76
4 71
5 49
6 42
7 39
8 33
9 16
10 1
11 100
12 92
13 77
14 64
15 63
16 48
17 41
18 40
19 18
20 15
答案3
得分: 0
以下是翻译好的部分:
你可以使用 numpy 的 choice 方法(numpy.random.choice)。
这是我的代码:
from collections.abc import Sequence
import numpy as np
def get_it(high, length, n_repeat, replace=False):
rng = np.random.default_rng()
match length:
case int():
partial_seqs = [rng.choice(high+1, length, replace=replace) for _ in range(n_repeat)]
case Sequence():
partial_seqs = [rng.choice(high+1,
length[i%len(length)], # 循环使用如果 len(length) < n_repeat
replace=replace)
for i in range(n_repeat)]
case _:
raise TypeError('不支持的长度类型')
partial_seqs = [np.flip(np.sort(x)) for x in partial_seqs]
return list(np.concatenate(partial_seqs))
high = 10
length = [5, 3]
n_repeat = 5
get_it(high, length, n_repeat)
示例输出:
[10, 9, 7, 1, 0, 6, 4, 0, 8, 6, 5, 4, 2, 6, 5, 0, 7, 6, 5, 4, 2]
如果你将一个标量整数传递给 *length*,那么将重复使用固定的长度,例如,所有的部分序列将具有相同的 *length*。
要创建具有任意长度的部分(子)序列,你可以将类似列表的 *length* 传递给函数。请注意,如果你给定 `length = [5, 3]` 和 `n_repeat = 5`,那么在重复 5 次时,它会以循环方式使用 *length*。换句话说,*length* 将扩展为 [5, 3, 5, 3, 5]。如果你输入 `length = [3, 2, 5]` 和 `n_repeat = 2`,只有前两个元素将被使用。换句话说,将使用 `length = [3, 2]`。
关于 *replace*,如果将其设置为 *False*,子序列将具有唯一的数字,即部分序列将单调递减。否则(例如,`replace=True`),部分序列将递减,并且部分序列中可能会有相同的数字。
[1]: https://numpy.org/doc/stable/reference/random/generated/numpy.random.choice.html
<details>
<summary>英文:</summary>
You can use choice method of numpy([numpy.random.choice][1]).
Here is my code:
from collections.abc import Sequence
import numpy as np
def get_it(high, length, n_repeat, replace=False):
rng = np.random.default_rng()
match length:
case int():
partial_seqs = [rng.choice(high+1, length, replace=replace) for _ in range(n_repeat)]
case Sequence():
partial_seqs = [rng.choice(high+1,
length[i%len(length)], # circular if len(length) < n_repeat
replace=replace)
for i in range(n_repeat)]
case _:
raise TypeError('Unsupported type of length')
partial_seqs = [np.flip(np.sort(x)) for x in partial_seqs]
return list(np.concatenate(partial_seqs))
high = 10
length = [5, 3]
n_repeat = 5
get_it(high, length, n_repeat)
Sample output:
[10, 9, 7, 1, 0, 6, 4, 0, 8, 6, 5, 4, 2, 6, 5, 0, 7, 6, 5, 4, 2]
If you pass a scalar integer into *length*, then the fixed length will be repeatedly used, e.g., all partial sequences will have the same *length*.
To make partial (sub)sequences with arbitrary lengths, you can pass list-like *length* to the function.
Note that if you give `length = [5, 3]` and `n_repeat = 5`, then to repeat 5 times, it uses *length* in circular manner. In other words, *length* will be expanded to [5, 3, 5, 3, 5]. If you feed like `length = [3, 2, 5]` and `n_repeat = 2`, only first two elements will be used. In other words, `length = [3, 2]` will be used instead.
About *replace*, if you set it as *False*, a subsequence will have unique numbers, i.e., partial sequences will be monotonically-decreasing. Otherwise (e.g., `replace=True`), partial sequences will be decreasing, and there might be the same numbers in a partial sequence.
[1]: https://numpy.org/doc/stable/reference/random/generated/numpy.random.choice.html
</details>
# 答案4
**得分**: 0
根据您提供的代码,以下是翻译好的部分:
```python
从您期望的结果中的“8”的重复来看,似乎您不需要数字在这10个值的块中保持不同。在这种情况下,您可以简单地在循环(或理解)中使用`random.sample`来获取10个数字,然后输出之前对它们进行排序:
from random import sample
def randChunks(nums, size, count):
for _ in range(count):
yield from sorted(sample(nums, size), reverse=True)
输出:
for i, n in enumerate(randChunks(range(1, 96), 10, 3), 1):
print(i, n)
1 93
2 92
3 88
4 85
5 74
6 62
7 54
8 23
9 15
10 6
11 93
12 76
13 37
14 35
15 28
16 27
17 26
18 18
19 16
20 14
21 85
22 78
23 73
24 70
25 66
26 52
27 40
28 32
29 25
30 19
如果您需要这些数字在各个块之间完全不同,您可以使用`random.sample`来对整个数字集进行随机化,然后使用enumerate为每个块分配组号。通过按组号(索引除以大小)和值的负值对块进行排序,直接产生了所期望的分块和逆序:
from random import sample
def randChunks(nums, size):
chunks = enumerate(sample(nums, len(nums)))
return (v for _, v in sorted(chunks, key=lambda x: (x[0] // size, -x[1])))
输出:
for i, n in enumerate(randChunks(range(1, 101), 10), 1):
print(i, n)
1 89
2 88
3 79
4 78
5 72
6 59
7 48
8 40
9 29
10 24
11 82
12 75
13 70
14 60
15 49
16 37
17 22
18 15
19 12
20 2
21 95
22 85
...
95 62
96 50
97 31
98 19
99 16
100 5
*如果值的数量不是块大小的倍数,最后一个块将比指定的大小小。如果这是一个问题,您可以在第一行调整样本数(`len(nums)//size*size`而不是`len(nums)`)*
*或者,您可以使用多个迭代器的多个副本(每个块项目一个副本)编写该函数,然后使用zip:*
def randChunks(nums, size):
chunks = size * [iter(sample(nums, len(nums)))]
return (v for c in zip(*chunks) for v in sorted(c)[::-1])
如果您需要进一步的帮助,请随时告诉我。
英文:
From the repetition of 8
in your expected result, it seems you don't need the numbers to be distinct across the 10 value chunks. In that case, you can simply use random.sample
in a loop (or comprehension) to get 10 numbers that you sort before output:
from random import sample
def randChunks(nums,size,count):
for _ in range(count):
yield from sorted(sample(nums,size),reverse=True)
output:
for i,n in enumerate(randChunks(range(1,96),10,3),1):
print(i,n)
1 93
2 92
3 88
4 85
5 74
6 62
7 54
8 23
9 15
10 6
11 93
12 76
13 37
14 35
15 28
16 27
17 26
18 18
19 16
20 14
21 85
22 78
23 73
24 70
25 66
26 52
27 40
28 32
29 25
30 19
If you need the number to be all different across the chunks, you could use random.sample
to randomize the whole set of numbers and enumerate to assign group numbers to each chunk. Sorting the chunks by group number (index divided by size) and negative of value will directly produce the expected chunking and reversed order:
from random import sample
def randChunks(nums,size):
chunks = enumerate(sample(nums,len(nums)))
return (v for _,v in sorted(chunks,key=lambda x:(x[0]//size,-x[1])))
output:
for i,n in enumerate(randChunks(range(1,101),10),1):
print(i,n)
1 89
2 88
3 79
4 78
5 72
6 59
7 48
8 40
9 29
10 24
11 82
12 75
13 70
14 60
15 49
16 37
17 22
18 15
19 12
20 2
21 95
22 85
...
95 62
96 50
97 31
98 19
99 16
100 5
If the number of values is not a multiple of the chunk size, the last chunk will be smaller than the specified size. If that is an issue, you can adjust the number of samples on the first line (len(nums)//size*size
instead of len(nums)
)
Or, you could write the function using zip on multiple copies of an iterator (one copy for each chunk item):
def randChunks(nums,size):
chunks = size*[iter(sample(nums,len(nums)))]
return (v for c in zip(*chunks) for v in sorted(c)[::-1])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论