python 如何在特定范围内递增列表中的值

kse8i1jr  于 2022-12-10  发布在  Python
关注(0)|答案(5)|浏览(142)

我有一个列表l =[253, 59, 2, 0, 0, 0, 0, 0],我想为列表中的每个元素设置一个(0, 255)的范围。我想在python中实现它。我想递增*********************************************************************
每次迭代后的输出应如下所示:

l =[253, 59, 2, 0, 0, 0, 0, 0]
l =[254, 59, 2, 0, 0, 0, 0, 0]
l =[255, 59, 2, 0, 0, 0, 0, 0]
l =[0, 60, 2, 0, 0, 0, 0, 0]
l =[1, 60, 2, 0, 0, 0, 0, 0]
.
.
.
.
l =[255, 60, 2, 0, 0, 0, 0, 0]
l =[0, 61, 2, 0, 0, 0, 0, 0]
lb3vh1jj

lb3vh1jj1#

单向循环:

def inc_list(l):
    for i in range(len(l)):
        l[i] += 1
        if l[i] > 255:
            l[i] = 0
        else:
            return

for _ in range(300):
    print(l)
    inc_list(l)

或者,递归解决方案:

def inc_list(l):
    if not l:
        return []
    elif l[0] == 255:
        return [0] + inc_list(l[1:])
    else:
        return [l[0] + 1] + l[1:]

for _ in range(300):
    print(l)
    l = inc_list(l)
jjhzyzn0

jjhzyzn02#

tl;dr:一行程序(仅在小端序计算机上有效)为

import struct
list(struct.pack('l', struct.unpack('l', bytes(start))[0]+1))

1-以64位计数

从另一个Angular 来看,你似乎在计算一个代表64位整数的8个字节的列表,小字节序...为什么不这样做呢?

def plusOne(l):
   n=0
   b=1
   for dg in l:
       n+=b*dg
       b*=256
   n+=1
   res=[]
   for i in range(len(l)):
       res.append(n%256)
       n//=256
   return res

事实上,这个答案并不比其他答案快。我猜测,它甚至慢得多(还没有计时。但是,嗯,它显然更复杂)。
但是如果您想要的只是一个计数器,那么您可以通过只保留一个整数作为状态值来简化,并生成列表

2-迭代器

def listCounter(start, size):
    while True:
        res=[]
        x=start
        for i in range(size):
            res.append(x%256)
            x//=256
        yield res
        start+=1

myiter=listCounter(254, 8)
print(next(myiter))
print(next(myiter))
for _,l in zip(range(20),listCounter(510,8)):
    print(l)

3-结构(使用内部表示)

如果您相信您使用的是基于二进制小字节序的机器(二进制,好吧,在这个世界上,我想所有的机器都是.小字节序的,不是所有的,但可能是您的),那么您甚至可以依靠cpu来完成这一任务

import struct
l=[254, 255, 0, 0, 1, 0, 0, 0]
nextl=list(struct.pack('l', struct.unpack('l', bytes(l))[0]+1))

或者在迭代器的for中
第一个

说明

bytes(l)是包含l中8个字节的字节数组
bytes(l) -> b'\xfe\xff\x00\x00\x01\x00\x00\x00'
这8个字节是一个数字的64位表示。我们可以通过struct.unpack提取,指定格式l(64位整数)
struct.unpack('l', bytes(l)) → (4295032830,)
它是元组的形式,因为我们可以要求一系列不同的数字。
struct.unpack('l', bytes(l))[0] → 4295032830
我们可以增加它
struct.unpack('l', bytes(l))[0]+1 → 4295032831
我们可以使用pack得到这个新整数的64位字节数组表示
struct.pack('l',struct.unpack('l', bytes(l))[0]+1) → b'\xff\xff\x00\x00\x01\x00\x00\x00'
这个bytes数组只是0到255之间的数字,我们可以很容易地将其转换为列表
list(struct.pack('l',struct.unpack('l', bytes(l))[0]+1)) → [255, 255, 0, 0, 1, 0, 0, 0]

1l5u6lss

1l5u6lss3#

这个问题等价于在基数为256的位置数制中寻找连续整数的表示(但也可以使用混合基数)。

numpy拆开和解开

对于较小的列表,您可以找到l = [253, 59, 2, 0]形式的整数

value = np.ravel_multi_index(l, [256] * 4, order='F') #sets value to 146429

然后使用np.unravel_index返回第一个整数的表示,比如说,5个整数:

np.transpose(np.unravel_index(np.arange(value, value+5), [256]*4, order='F'))
>>> array([[253,  59,   2,   0],
           [254,  59,   2,   0],
           [255,  59,   2,   0],
           [  0,  60,   2,   0],
           [  1,  60,   2,   0]], dtype=int64)

大型案例

在您的例子中,dimension = [256] * 8是必需的。这太大了,因为整数不能超过numpy中的2**63,并且会抛出ValueError。在这种情况下,您可以实现自己的方式来替换np.ravel_multi_indexnp.unravel_index

shape = np.cumprod([1, 256, 256, 256, 256, 256, 256, 256], dtype=np.int64)
value = np.dot(l, shape) #same 146429

def unravel(values, shape=[256] * 8):
    steps = len(values)
    result_arr = np.empty(shape=(len(shape), steps), dtype=int)
    for j in range(len(shape)):
        result_arr[j] = values % shape[j]
        values =  values // shape[j]
    return np.transpose(result_arr)

unravel(np.arange(value, value+5))
>>> array([[253,  59,   2,   0,   0,   0,   0,   0],
           [254,  59,   2,   0,   0,   0,   0,   0],
           [255,  59,   2,   0,   0,   0,   0,   0],
           [  0,  60,   2,   0,   0,   0,   0,   0],
           [  1,  60,   2,   0,   0,   0,   0,   0]])

请注意,在所有情况下只需要8次迭代,因此它应该比仅用Python的方式更快。

xxls0lw8

xxls0lw84#

对于循环,

array = [253, 59, 2, 0, 0, 0, 0, 0]
index = 0
while index < len(array):
    while array[index]<256:
        array[index] += 1
        print(array)
    array[index] = 0
    index += 1
nc1teljy

nc1teljy5#

纯Python皮款式:

l = [253, 59, 2, 0, 0, 0, 0, 0]

pos = 0
n_iter = 10
step = 0
for step in range(n_iter):
    for pos in range(len(l)):
        if l[pos] < 255:
            l[pos] += 1
            break
        else:
            l[pos] = 0
    print(f'step {step+1}: {l}')

输出量:

step 1: [254, 59, 2, 0, 0, 0, 0, 0]
step 2: [255, 59, 2, 0, 0, 0, 0, 0]
step 3: [0, 60, 2, 0, 0, 0, 0, 0]
step 4: [1, 60, 2, 0, 0, 0, 0, 0]
step 5: [2, 60, 2, 0, 0, 0, 0, 0]
step 6: [3, 60, 2, 0, 0, 0, 0, 0]
step 7: [4, 60, 2, 0, 0, 0, 0, 0]
step 8: [5, 60, 2, 0, 0, 0, 0, 0]
step 9: [6, 60, 2, 0, 0, 0, 0, 0]
step 10: [7, 60, 2, 0, 0, 0, 0, 0]

相关问题