Skip to main content
 首页 » 编程设计

python之用随机 1 填充稀疏列表

2025年05月04日11lexus

我需要用随机位置的几个 1 填充一个列表。我可以成功地创建一个随机数列表:

from random import randint 
l = [randint(0,1023) for _ in range(0,10)] 

如何在 l 指定的位置用 1 填充列表?

请您参考如下方法:

稀疏列表

我对“稀疏列表”的理解是大多数(比方说,超过 95%)的值将为零,并且出于内存效率的原因,您不希望存储 这些(cf. Sparse array )。

列表理解

使用您的列表理解,您可以使用 Conditional Expression Resolution (foo if condition else bar) 判断是一还是零在那个位置。例如:

In [1]: from random import randint 
 
In [2]: l = [randint(0,1023) for _ in range(0,10)] 
 
In [3]: l 
Out[3]: [987, 356, 995, 192, 21, 22, 1013, 375, 796, 339] 
 
In [4]: 1 if 987 in l else 0 
Out[4]: 1 
 
In [5]: 1 if 988 in l else 0 
Out[5]: 0 

这意味着您不需要填充您在问题中提到的第二个列表,您可以遍历 0 - 1023 范围并使用:

1 if index in l else 0 

词典理解

或者,您可以使用 dictionary comprehension .我认为这更具可读性:

In [1]: from random import randint 
In [2]: l = {randint(0, 1023): 1 for _ in xrange(0, 10)} 

这将生成一个像这样的字典:

In [3]: l 
Out[3]:  
{216: 1, 
 381: 1, 
 384: 1, 
 392: 1, 
 396: 1, 
 472: 1, 
 585: 1, 
 630: 1, 
 784: 1, 
 816: 1} 

然后您访问元素,指定默认值零。如果设置了请求位置的值,您将获得一个:

In [4]: l.get(216, 0) 
Out[4]: 1 

如果未设置该值,您将得到一个零:

In [5]: l.get(217, 0) 
Out[5]: 0 

获取职位列表:

In [6]: l.keys() 
Out[6]: [384, 392, 472, 630, 216, 585, 396, 381, 784, 816] 

上述两种方法的缺陷

randint(0, 1023) 可能多次发出相同的数字,导致冲突,这将导致少于所需数量。 p>

将它们捆绑在一起

我会将基于字典的实现包装在 class 中,以便于(重新)使用。

from random import randint 
 
 
class RandomSparseList(object): 
    def __init__(self, size, min_bits, max_bits): 
        self.size = int(size) 
        self.bits = {} 
        self.bits_set = randint(min_bits, max_bits) 
        while self.bits_set > len(self.bits): 
            self.bits[randint(0, self.size)] = 1  
 
    def __len__(self): 
        return self.size 
 
    def __getitem__(self, index): 
        if index < 0 or index >= self.size: 
            raise IndexError 
        return self.bits.get(int(index), 0) 
 
    def __iter__(self): 
        for i in xrange(self.size): 
            yield self.__getitem__(i) 
 
    def __contains__(self, index): 
        return index in self.bits 
 
    def __repr__(self): 
        return '[{}]'.format(', '.join(str(x) for x in self)) 
 
    def set_bits(self): 
        return self.bits.keys() 

示例用法

我已经把这个类放在一个文件中:

In [1]: from random_sparse_list import RandomSparseList 

创建一个实例:

In [2]: rsl = RandomSparseList(1024, 10, 40) 

检查列表的长度:

In [3]: len(rsl) 
Out[3]: 1024 

设置了哪些位?

In [4]: rsl.set_bits() 
Out[4]:  
[523, 
 400, 
 285, 
 158, 
 419, 
 434, 
 701, 
 67, 
 843, 
 846, 
 591, 
 720, 
 470, 
 864, 
 912, 
 739, 
 996, 
 485, 
 489, 
 234, 
 1005, 
 573, 
 381, 
 784] 

24:肯定在10-40之间。

随机访问:

In [5]: rsl[523] 
Out[5]: 1 
 
In [6]: rsl[524] 
Out[6]: 0 

位设置了吗?

In [7]: 400 in rsl 
Out[7]: True 
 
In [8]: 401 in rsl 
Out[8]: False 

遍历列表:

In [9]: for index, value in enumerate(rsl): 
   ...:     if value: 
   ...:         print '{} found at index {}'.format(value, index) 
   ...:          
1 found at index 67 
1 found at index 158 
1 found at index 234 
1 found at index 285 
1 found at index 381 
1 found at index 400 
1 found at index 419 
1 found at index 434 
1 found at index 470 
1 found at index 485 
1 found at index 489 
1 found at index 523 
1 found at index 573 
1 found at index 591 
1 found at index 701 
1 found at index 720 
1 found at index 739 
1 found at index 784 
1 found at index 843 
1 found at index 846 
1 found at index 864 
1 found at index 912 
1 found at index 996 
1 found at index 1005 

字符串表示:

In [10]: rsl 
Out[10]: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

注意事项

A set基于 -based 的实现会更加内存有效,但是 dict上面的内容可以很容易地更改为包含(随机或其他)0 和 1 以外的值。

更新

受到这个问题和缺乏标准稀疏 list 实现的启发,我添加了一个 sparse_list实现到奶酪店。您可以使用 pip install sparse_list 安装它,然后 RandomSparseList 实现对您来说要简单得多:

from sparse_list import SparseList 
from random import randint 
 
 
class RandomSparseList(SparseList): 
    def __init__(self, size, min_bits, max_bits): 
        super(RandomSparseList, self).__init__(size, 0) 
        self.bits = randint(min_bits, max_bits) 
        while self.bits > len(self.elements): 
            self.elements[randint(0, self.size)] = 1 

这将与上面的示例完全一样,但有一些额外的功能,例如扩展切片。您可以阅读(并参与)来源 on GitHub .