gpt4 book ai didi

python - 创建特定模式的两个列表的快速方法

转载 作者:行者123 更新时间:2023-12-04 08:01:40 25 4
gpt4 key购买 nike

我想创建某个partern的两个列表(显然它不需要是一个列表,可以是元组,数组,numpy.array,见下面的编辑),让我们称它们为list_1和list_2
list_1 的模式可以描述为 (i 是一个整数)
{i}, {i, i + 17}, {i, i+17 , i + 17 + 17}, {i, i + 17, i + 17 + 17, i + 17 + 17 + 17},
但是模式出现了两次,这意味着结果列表看起来像

list_1 = [i, i, i + 17, i, i + 17 , i + 34, i, i + 17, i + 34, i + 51, 
i, i, i + 17, i, i + 17 , i + 34, i, i + 17, i + 34, i + 51]
目前我是这样做的(在这个例子中 i = 2)
some_limit = 5    
list_1 = [17 * x + i for b in range(some_limit + 1) for x in range(b)]
list_1 += list_1
结果
[2, 2, 19, 2, 19, 36, 2, 19, 36, 53, 2, 19, 36, 53, 70, 2, 2, 19, 2, 19, 36, 2, 19, 36, 53, 2, 19, 36, 53, 70]
当 some_limit 是一个大数字时,这需要时间。有没有更快的方法?
list_2 有一个模式可以描述为(j 是一个整数)
{j} {j+1, j+1}, {j+2, j+2, j+2}, {j+3, j+3, j+3, j+3}
这种模式也出现了两次,但有一个转变,这意味着结果列表看起来像
list_2 = [j, j+1, j+1, j+2, j+2, j+2, j+3, j+3, j+3, j+3,
j+shift, j+1+shift, j+1+shift, j+2+shift, j+2+shift, j+2+shift, j+3+shift, j+3+shift, j+3+shift, j+3+shift,
目前我是这样做的(在这个例子中 j = 0)
some_limit = 5
arithemic_list = [k for k in range(some_limit + 1)]
rows_index_temp = [item -1 + some_limit * j * 2 for item, count in zip(arithemic_list, arithemic_list) for k in range(count)]
rows_index_temp += [some_limit + elem for elem in rows_index_temp]
结果
[0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9]
当 some_limit 是一个大数字时,这需要时间。有没有更快的方法?
编辑
这用于为优化包 cvxopt 创建稀疏矩阵。通过为元素提供行和列索引来构建矩阵。例如,一个 3x3 单位矩阵由 3 个列表创建,元素 = [1,1,1],行 = [0, 1, 2] 和列 = [0, 1, 2]。我的矩阵非常大,这意味着列表将非常大。
从文档

cvxopt.spmatrix(x, I, J[, size[, tc ] ])I and J are sequences of integers (lists, tuples, array arrays, . . . ) or integer matrices (matrix objects withtypecode 'i'), containing the row and column indices of the nonzero entries. The lengths of I and J mustbe equal. If they are matrices, they are treated as lists of indices stored in column-major order, i.e., as listslist(I), respectively, list(J)


https://readthedocs.org/projects/cvxopt/downloads/pdf/1.2.0/
示例
假设我们想创建以下矩阵:
[ 1.00e+00     0         0         0         0    ]
[ 2.00e+00 0 0 3.00e+00 0 ]
[ 0 0 0 0 4.00e+00]
我们只对非零元素感兴趣,我们可以将它们分组为
element   row   column    
1 0 0
2 1 0
3 1 3
4 2 4
因此,通过有
elements = [1,2,3,4,0] 
rows = [0,1,1,2, 3]
columns = [0,0, 3, 4, 4]
print(spmatrix(elements, rows, columns))
[ 1.00e+00 0 0 0 0 ]
[ 2.00e+00 0 0 3.00e+00 0 ]
[ 0 0 0 0 4.00e+00]
请注意,只要元素、行、列组合在一起,顺序就无关紧要。因此,这将是等效的。
elements = [4,2,3,1] 
rows = [2,1,1,0]
columns = [4,0, 3,0]
print(spmatrix(elements, rows, columns))
[ 1.00e+00 0 0 0 0 ]
[ 2.00e+00 0 0 3.00e+00 0 ]
[ 0 0 0 0 4.00e+00]
我想创造什么? (some_limit = 3)
enter image description here
这基本上是两个下三角矩阵的串联,其元素之间具有恒定的移位。那么我们如何描述这个矩阵呢?
如果我们关注包含 -1:s 的“上”下三角部分。
我们可以分组为
element   row   column    
-1 0 2
-1 1 2
-1 1 19
-1 2 2
-1 2 19
-1 2 36
只有 1:s 的“下”三角形部分可以分组为
我们可以分组为
element   row   column    
1 3 2
1 4 2
1 4 19
1 5 2
1 5 19
1 5 36
这一起成为
element   row   column    
-1 0 2
-1 1 2
-1 1 19
-1 2 2
-1 2 19
-1 2 36
1 3 2
1 4 2
1 4 19
1 5 2
1 5 19
1 5 36
或者,
element   row   column    
-1 0 2
-1 1 2
-1 1 2 + 17
-1 2 2
-1 2 2 + 17
-1 2 2 + 2*17
1 1 + 2 2
1 2 + 2 2
1 2 + 2 2 + 17
1 3 + 2 2
1 3 + 2 2 + 17
1 3 + 2 2 + 2*17
由于顺序不计算,只要元素、行、列组合在一起,可能存在我尚未考虑的“更好”模式。
该矩阵的大小与描述元素、行和列的列表中的元素数量直接相关。我希望 some_limit >=4343 => 每个列表元素、行和列的长度将是
(4343*(4343 + 1)/2)*2 爆炸速度相当快......
some_limit
4343
len(list_1)
18865992
#size_of_matrix
<34744x73831 sparse matrix, tc='d', nnz=75463969>

最佳答案

您可以将列表推导式转换为生成器表达式,然后您不必一次创建整个列表,而是可以根据需要生成值。特别注意我添加的附加循环,这样您就不必创建整个列表,然后向其自身添加副本。

i, j, limit, shift = 2, 0, 5, 10

gen_1 = (17 * x + i for _ in range(2) # repeat twice
for b in range(limit) # len of subsegments
for x in range(b+1)) # multiplier

gen_2 = (j + b + s for s in (0, 10) # repeat with shift
for b in range(limit) # len of subsegments
for _ in range(b+1)) # repeat b times
然后,您可以根据需要迭代这些值(或仍然从所有值创建一个列表):
for x in gen_1:
print(x)
print(list(gen_2))

关于python - 创建特定模式的两个列表的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66436808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com