使用随机1填充稀疏列表

Tom*_*aly 1 python

我需要在随机位置填充一些带有1个的列表.我可以成功创建一个随机数列表:

from random import randint
l = [randint(0,1023) for _ in range(0,10)]
Run Code Online (Sandbox Code Playgroud)

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

Pao*_*olo 8

我需要在随机位置创建一个0到40的大型列表,以对算法进行基准测试.

这项工作可能适合你吗?

import random

zeros = [0] * 1024
ones = [1] * random.randint(10, 40)
l =  zeros + ones
random.shuffle(l)

# the list l contains many zeros and 10 - 40 1's in random places.

where_the_ones_are = [i for i, x in enumerate(l) if x == 1] 
Run Code Online (Sandbox Code Playgroud)


Joh*_*web 7

稀疏列表

我对"稀疏列表"的理解是,大多数(例如,超过95%)的值将为零,并且出于内存效率的原因,您不希望存储这些(参见 稀疏数组).

列表理解

使用列表推导,您可以使用条件表达式解析(foo if 条件 else )来确定一个或零是否在该位置.例如:

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
Run Code Online (Sandbox Code Playgroud)

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

1 if index in l else 0
Run Code Online (Sandbox Code Playgroud)

字典理解

或者,您可以使用字典理解.我认为这更具可读性:

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

这将生成如下字典:

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}
Run Code Online (Sandbox Code Playgroud)

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

In [4]: l.get(216, 0)
Out[4]: 1
Run Code Online (Sandbox Code Playgroud)

如果未设置该值,您将获得零:

In [5]: l.get(217, 0)
Out[5]: 0
Run Code Online (Sandbox Code Playgroud)

要获得职位列表:

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

上述两种方法都存在缺陷

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

把它们捆绑在一起

我会将基于字典的实现包装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()
Run Code Online (Sandbox Code Playgroud)

用法示例

我把它class放在一个文件中:

In [1]: from random_sparse_list import RandomSparseList
Run Code Online (Sandbox Code Playgroud)

创建一个实例:

In [2]: rsl = RandomSparseList(1024, 10, 40)
Run Code Online (Sandbox Code Playgroud)

检查列表的长度:

In [3]: len(rsl)
Out[3]: 1024
Run Code Online (Sandbox Code Playgroud)

设置了哪些位?

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]
Run Code Online (Sandbox Code Playgroud)

24:这肯定在10-40的范围内.

随机访问:

In [5]: rsl[523]
Out[5]: 1

In [6]: rsl[524]
Out[6]: 0
Run Code Online (Sandbox Code Playgroud)

有点固定吗?

In [7]: 400 in rsl
Out[7]: True

In [8]: 401 in rsl
Out[8]: False
Run Code Online (Sandbox Code Playgroud)

迭代列表:

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
Run Code Online (Sandbox Code Playgroud)

字符串表示:

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]
Run Code Online (Sandbox Code Playgroud)

注意

set基实现将是更有效的存储器,但字典上面可以容易地改变,以含有(随机或以其它方式)值以外01.

更新

受这个问题和缺乏标准稀疏list实现的启发,我在Cheese Shop中添加了一个 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
Run Code Online (Sandbox Code Playgroud)

这将与上面的示例完全相同,但有一些附加功能,如扩展切片.您可以在GitHub上阅读(并参与)源代码.

  • +1用于深刻,格式良好且有用的答案. (2认同)