生成多组递减数字的Python代码

huangapple go评论69阅读模式
英文:

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))
英文:

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, with reverse=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) &lt; n_repeat
                                           replace=replace)
                                for i in range(n_repeat)]
            case _:
                raise TypeError(&#39;Unsupported type of length&#39;)
            
        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])

huangapple
  • 本文由 发表于 2023年6月8日 21:09:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76432196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定