有没有一种简单的方法可以将列表的元素相互映射?

时间:2021-06-22 03:59:54

标签: python list

我正在使用 python。基本上我有一个大列表,每个值都有一个三重索引:(i, j, t):

Y_1,2,1
Y_1,3,1

等等。

我想要做的是专门提取值:Y_i,j,tY_j,i,t,但我遇到了一些困难。

例如,我希望能够提取:Y_1,2,1Y_2,1,1Y_1,3,4Y_3,1,4...

要填充我使用的数据:

N = 6
T = 2 * N - 2
list_ijt = []
    
for t in range(1, T + 1):
    for i in range(1, N + 1):
        for j in range(1, N + 1):
            # Avoid making Y_i,j=i,t index
            if j == i:
                continue
            element = "Y" + str(i) + ',' + str(j) + ',' + str(t)
            list_ijt.append(element)

对于一般情况 n 有什么方法可以做到这一点吗?用字典会更容易吗?我已经尝试并尝试提出一些算法或方程式,例如

for n in range(len(list_ijt)):
     match_index = 4 * (n + 1) + (n + 1) 
     print(list_ijt[n], list_ijt[match_index])

但无济于事,也不知道如何将其推广到任何 n(上面的示例适用于 n = 6)。

示例列表:

print(list_ijt)
['Y1,2,1', 'Y1,3,1', 'Y1,4,1', 'Y1,5,1', 'Y1,6,1', 'Y2,1,1', 'Y2,3,1', 'Y2,4,1', 'Y2,5,1', 'Y2,6,1', 'Y3,1,1', 'Y3,2,1', 'Y3,4,1', 'Y3,5,1', 'Y3,6,1', 'Y4,1,1', 'Y4,2,1', 'Y4,3,1', 'Y4,5,1', 'Y4,6,1', 'Y5,1,1', 'Y5,2,1', 'Y5,3,1', 'Y5,4,1', 'Y5,6,1', 'Y6,1,1', 'Y6,2,1', 'Y6,3,1', 'Y6,4,1', 'Y6,5,1', 'Y1,2,2', 'Y1,3,2', 'Y1,4,2', 'Y1,5,2', 'Y1,6,2', 'Y2,1,2', 'Y2,3,2', 'Y2,4,2', 'Y2,5,2', 'Y2,6,2', 'Y3,1,2', 'Y3,2,2', 'Y3,4,2', 'Y3,5,2', 'Y3,6,2', 'Y4,1,2', 'Y4,2,2', 'Y4,3,2', 'Y4,5,2', 'Y4,6,2', 'Y5,1,2', 'Y5,2,2', 'Y5,3,2', 'Y5,4,2', 'Y5,6,2', 'Y6,1,2', 'Y6,2,2', 'Y6,3,2', 'Y6,4,2', 'Y6,5,2', 'Y1,2,3', 'Y1,3,3', 'Y1,4,3', 'Y1,5,3', 'Y1,6,3', 'Y2,1,3', 'Y2,3,3', 'Y2,4,3', 'Y2,5,3', 'Y2,6,3', 'Y3,1,3', 'Y3,2,3', 'Y3,4,3', 'Y3,5,3', 'Y3,6,3', 'Y4,1,3', 'Y4,2,3', 'Y4,3,3', 'Y4,5,3', 'Y4,6,3', 'Y5,1,3', 'Y5,2,3', 'Y5,3,3', 'Y5,4,3', 'Y5,6,3', 'Y6,1,3', 'Y6,2,3', 'Y6,3,3', 'Y6,4,3', 'Y6,5,3', 'Y1,2,4', 'Y1,3,4', 'Y1,4,4', 'Y1,5,4', 'Y1,6,4', 'Y2,1,4', 'Y2,3,4', 'Y2,4,4', 'Y2,5,4', 'Y2,6,4', 'Y3,1,4', 'Y3,2,4', 'Y3,4,4', 'Y3,5,4', 'Y3,6,4', 'Y4,1,4', 'Y4,2,4', 'Y4,3,4', 'Y4,5,4', 'Y4,6,4', 'Y5,1,4', 'Y5,2,4', 'Y5,3,4', 'Y5,4,4', 'Y5,6,4', 'Y6,1,4', 'Y6,2,4', 'Y6,3,4', 'Y6,4,4', 'Y6,5,4', 'Y1,2,5', 'Y1,3,5', 'Y1,4,5', 'Y1,5,5', 'Y1,6,5', 'Y2,1,5', 'Y2,3,5', 'Y2,4,5', 'Y2,5,5', 'Y2,6,5', 'Y3,1,5', 'Y3,2,5', 'Y3,4,5', 'Y3,5,5', 'Y3,6,5', 'Y4,1,5', 'Y4,2,5', 'Y4,3,5', 'Y4,5,5', 'Y4,6,5', 'Y5,1,5', 'Y5,2,5', 'Y5,3,5', 'Y5,4,5', 'Y5,6,5', 'Y6,1,5', 'Y6,2,5', 'Y6,3,5', 'Y6,4,5', 'Y6,5,5', 'Y1,2,6', 'Y1,3,6', 'Y1,4,6', 'Y1,5,6', 'Y1,6,6', 'Y2,1,6', 'Y2,3,6', 'Y2,4,6', 'Y2,5,6', 'Y2,6,6', 'Y3,1,6', 'Y3,2,6', 'Y3,4,6', 'Y3,5,6', 'Y3,6,6', 'Y4,1,6', 'Y4,2,6', 'Y4,3,6', 'Y4,5,6', 'Y4,6,6', 'Y5,1,6', 'Y5,2,6', 'Y5,3,6', 'Y5,4,6', 'Y5,6,6', 'Y6,1,6', 'Y6,2,6', 'Y6,3,6', 'Y6,4,6', 'Y6,5,6', 'Y1,2,7', 'Y1,3,7', 'Y1,4,7', 'Y1,5,7', 'Y1,6,7', 'Y2,1,7', 'Y2,3,7', 'Y2,4,7', 'Y2,5,7', 'Y2,6,7', 'Y3,1,7', 'Y3,2,7', 'Y3,4,7', 'Y3,5,7', 'Y3,6,7', 'Y4,1,7', 'Y4,2,7', 'Y4,3,7', 'Y4,5,7', 'Y4,6,7', 'Y5,1,7', 'Y5,2,7', 'Y5,3,7', 'Y5,4,7', 'Y5,6,7', 'Y6,1,7', 'Y6,2,7', 'Y6,3,7', 'Y6,4,7', 'Y6,5,7', 'Y1,2,8', 'Y1,3,8', 'Y1,4,8', 'Y1,5,8', 'Y1,6,8', 'Y2,1,8', 'Y2,3,8', 'Y2,4,8', 'Y2,5,8', 'Y2,6,8', 'Y3,1,8', 'Y3,2,8', 'Y3,4,8', 'Y3,5,8', 'Y3,6,8', 'Y4,1,8', 'Y4,2,8', 'Y4,3,8', 'Y4,5,8', 'Y4,6,8', 'Y5,1,8', 'Y5,2,8', 'Y5,3,8', 'Y5,4,8', 'Y5,6,8', 'Y6,1,8', 'Y6,2,8', 'Y6,3,8', 'Y6,4,8', 'Y6,5,8', 'Y1,2,9', 'Y1,3,9', 'Y1,4,9', 'Y1,5,9', 'Y1,6,9', 'Y2,1,9', 'Y2,3,9', 'Y2,4,9', 'Y2,5,9', 'Y2,6,9', 'Y3,1,9', 'Y3,2,9', 'Y3,4,9', 'Y3,5,9', 'Y3,6,9', 'Y4,1,9', 'Y4,2,9', 'Y4,3,9', 'Y4,5,9', 'Y4,6,9', 'Y5,1,9', 'Y5,2,9', 'Y5,3,9', 'Y5,4,9', 'Y5,6,9', 'Y6,1,9', 'Y6,2,9', 'Y6,3,9', 'Y6,4,9', 'Y6,5,9', 'Y1,2,10', 'Y1,3,10', 'Y1,4,10', 'Y1,5,10', 'Y1,6,10', 'Y2,1,10', 'Y2,3,10', 'Y2,4,10', 'Y2,5,10', 'Y2,6,10', 'Y3,1,10', 'Y3,2,10', 'Y3,4,10', 'Y3,5,10', 'Y3,6,10', 'Y4,1,10', 'Y4,2,10', 'Y4,3,10', 'Y4,5,10', 'Y4,6,10', 'Y5,1,10', 'Y5,2,10', 'Y5,3,10', 'Y5,4,10', 'Y5,6,10', 'Y6,1,10', 'Y6,2,10', 'Y6,3,10', 'Y6,4,10', 'Y6,5,10']

尝试过:

string = '\n'.join(list_ijt)
for t in range(T):
    for i in range(n):
        for j in range(i, n):
            s = get(i, j, t, string)
            if s:
                list_ijt.append(s)

2 个答案:

答案 0 :(得分:2)

使用

def get(i, j, t, string):
    def _get(i, j):
        pat = f'Y{i},{j},{t}'
        ind = string.find(pat)
        if ind >=0:
            return string[ind:ind+len(pat)]
    a, b = _get(i, j), _get(j, i)
    if a and b:
        return a, b
    
n = 3
T = 2*n-2
list_ijt = []

string = '\n'.join(your_list)
for t in range(T):
    for i in range(n):
        for j in range(i, n):
            if s := get(i, j, t, string):
                list_ijt.append(s)

print(list_ijt)
[('Y1,2,1', 'Y2,1,1'), ('Y1,2,2', 'Y2,1,2'), ('Y1,2,3', 'Y2,1,3')]

答案 1 :(得分:1)

如果您的数据与显示的完全一样(没有缺少元素或类似的东西),您就可以非常轻松地分析元素的位置。

总共有 TN * (N - 1) 元素块。每个块由 NN - 1 元素组成。每个段都有一个常数值 i。前 i - 1 元素用于 j < i,其余元素用于 j > i

因此对于给定的 i, j, t 选择,列表中的索引是

(t - 1) * N * (N - 1) + (i - 1) * (N - 1) + j - (j > i) - 1

表达式 (j > i) 的计算结果为 bool,它是一个 0 或 1 的整数。

这意味着 j, i, t 的索引由

给出
(t - 1) * N * (N - 1) + (j - 1) * (N - 1) + i - (i > j) - 1

因此,如果您在列表中有一个索引 k,您可以将其分解为多个组件并应用第二个公式。组件是

t = (k // (N * (N - 1))) + 1
i = (k % (N * (N - 1))) // (N - 1) + 1
j = k % (N - 1) + 1
j += (j >= i)

因此,您可以使用算术和布尔运算完全确定性地计算任何 k 的匹配索引。在这种特殊情况下,您不需要循环或字典。

你可以像这样写你的最终循环:

for k in range(len(list_ijt)):
    t = (k // (N * (N - 1))) + 1
    i = (k % (N * (N - 1))) // (N - 1) + 1
    j = k % (N - 1) + 1
    j += (j >= i)
    match_index = (t - 1) * N * (N - 1) + (j - 1) * (N - 1) + i - (i > j) - 1
    print(list_ijt[k], '->', list_ijt[match_index])