如何在Python中从一个列表转到另一个元组列表?

问题描述 投票:0回答:4

我的目标是用 python 创建面积图。为此,我需要一个元组列表,如下例所示。

我有这个清单:

outputs=[25,50,60,45]

我想将每个值分布在以下元组列表中:

a=(25,0,0,0)
b=(0,50,0,0)
c=(0,0,60,0)     
d=(0,0,0,45)    
    
    # repeat the tupples on the following list:
data= [a,a,b,b,c,c,d,d]

pS:此数据将允许为 xx 轴上的每个类别设置面积图的 2 个上角(即 yy 轴)。

python list tuples
4个回答
1
投票

一行,双重理解匹配对角线的索引,并重复元组两次。

[tuple(x if i==j else 0 for i in range(4)) for j,x in enumerate(outputs) for _ in range(2) ]

输出:

[(25, 0, 0, 0),
 (25, 0, 0, 0),
 (0, 50, 0, 0),
 (0, 50, 0, 0),
 (0, 0, 60, 0),
 (0, 0, 60, 0),
 (0, 0, 0, 45),
 (0, 0, 0, 45)]

但这不是最有效的,因为它构建了两次元组。


1
投票

任意

outputs
长度的快速:

a = [0] * len(outputs)
data = []
for i, a[i] in enumerate(outputs):
    t = *a,
    data += t, t
    a[i] = 0

基准测试(这并不重要,Jean-François Fabre 并没有试图让他们的速度更快,但我喜欢优化/基准测试,并且我想支持我的“快速”主张):

  0.44 ± 0.00 μs  Kelly_always4
  1.50 ± 0.00 μs  Kelly
  8.33 ± 0.02 μs  Jean_François_Fabre

代码(在线尝试!):

from timeit import timeit
from statistics import mean, stdev

def Kelly(outputs):
    a = [0] * len(outputs)
    data = []
    for i, a[i] in enumerate(outputs):
        t = *a,
        data += t, t
        a[i] = 0
    return data

def Kelly_always4(outputs):
    a,b,c,d=outputs
    a=(a,0,0,0)
    b=(0,b,0,0)
    c=(0,0,c,0)     
    d=(0,0,0,d)    
    return [a,a,b,b,c,c,d,d]

def Jean_François_Fabre(outputs):
    return [tuple(x if i==j else 0 for i in range(4)) for j,x in enumerate(outputs) for _ in range(2) ]

funcs = Kelly, Kelly_always4, Jean_François_Fabre

outputs = [25,50,60,45]

for f in funcs:
    print(f(outputs))

times = {f: [] for f in funcs}
def stats(f):
    ts = [t * 1e6 for t in sorted(times[f])[:10]]
    return f'{mean(ts):6.2f} ± {stdev(ts):4.2f} μs '

for _ in range(100):
    for f in funcs:
        t = timeit(lambda: f(outputs), number=100) / 100
        times[f].append(t)

for f in sorted(funcs, key=stats):
    print(stats(f), f.__name__)

1
投票

您可以使用

enumerate()
函数查找每个元素的索引并将其与元组的索引相对应:

data = []

for index, value in enumerate(outputs):
    l = [0, 0, 0, 0]
    l[index] = value
    
    l = tuple(l)

    data.append(l)
    data.append(l)

输出:

[(25, 0, 0, 0), 
 (25, 0, 0, 0), 
 (0, 50, 0, 0), 
 (0, 50, 0, 0), 
 (0, 0, 60, 0), 
 (0, 0, 60, 0), 
 (0, 0, 0, 45), 
 (0, 0, 0, 45)]

此方法循环遍历所有输出值,并使用

enumerate()
函数跟踪值索引。然后,创建一个临时列表 l 并将所有值设置为 0,索引处的值除外。最后,它使用
tuple()
函数将列表转换为元组,并使用
append()
函数将其添加到数据列表中。


1
投票

您可以通过提取中间有数字的填充元组的子集来构建元组:

outputs = [25,50,60,45]
    
data = [(0,0,0,n,0,0,0)[3-i:7-i] for i,n in enumerate(outputs) for _ in ".."]
   
print(*data,sep="\n")

(25, 0, 0, 0)
(25, 0, 0, 0)
(0, 50, 0, 0)
(0, 50, 0, 0)
(0, 0, 60, 0)
(0, 0, 60, 0)
(0, 0, 0, 45)
(0, 0, 0, 45)

您可以通过根据原始列表的大小设置填充来将其推广到任何大小的“输出”列表:

data = [tuple(a) for i,n in enumerate(outputs)  # each item at its column pos.
                 for a in [[0]*len(outputs)]    # padding = length 
                 for a[i] in [n,n] ]            # assigned twice
© www.soinside.com 2019 - 2024. All rights reserved.