Python - 在缺少索引的位置填充带零的元组列表

时间:2016-03-07 09:41:32

标签: python list-comprehension

我有一个元组列表:

[(0.0, 287999.70000000007),
(1.0, 161123.23000000001),
(2.0, 93724.140000000014),
(3.0, 60347.309999999983),
(4.0, 55687.239999999998),
(5.0, 29501.349999999999),
(6.0, 14993.920000000002),
(7.0, 14941.970000000001),
(8.0, 13066.229999999998),
(9.0, 10101.040000000001),
(10.0, 4151.6900000000005),
(11.0, 2998.8899999999999),
(12.0, 1548.9300000000001),
(15.0, 1595.54),
(16.0, 1435.98),
(17.0, 1383.01)]

可以看出,缺少索引(13和14)。 我想用零填充缺少的索引:

[(0.0, 287999.70000000007),
(1.0, 161123.23000000001),
(2.0, 93724.140000000014),
(3.0, 60347.309999999983),
(4.0, 55687.239999999998),
(5.0, 29501.349999999999),
(6.0, 14993.920000000002),
(7.0, 14941.970000000001),
(8.0, 13066.229999999998),
(9.0, 10101.040000000001),
(10.0, 4151.6900000000005),
(11.0, 2998.8899999999999),
(12.0, 1548.9300000000001),
(13.0, 0),
(14.0, 0),
(15.0, 1595.54),
(16.0, 1435.98),
(17.0, 1383.01)]

我用for loop做了一些丑陋的事(我没有添加它,因为我认为它不会对任何事情做出贡献......),但我想知道有没有优雅的方法来解决这个问题? (可能有3-4行list comprehension)。

3 个答案:

答案 0 :(得分:2)

直接for循环可能比列表理解更容易:

data = [(0.0, 287999.70000000007),
(1.0, 161123.23000000001),
(2.0, 93724.140000000014),
(3.0, 60347.309999999983),
(4.0, 55687.239999999998),
(5.0, 29501.349999999999),
(6.0, 14993.920000000002),
(7.0, 14941.970000000001),
(8.0, 13066.229999999998),
(9.0, 10101.040000000001),
(10.0, 4151.6900000000005),
(11.0, 2998.8899999999999),
(12.0, 1548.9300000000001),
(15.0, 1595.54),
(16.0, 1435.98),
(17.0, 1383.01)]

result = []
last = 0.0
for d in data:
    while last < d[0]:
        result.append((last, 0))
        last += 1
    result.append(d)
    last = d[0]+1

略短(包括列表理解):

result, last = [], 0.0
for d in data:
    result.extend((r,0) for r in range(int(last), int(d[0])))
    result.append(d)
    last = d[0]+1

答案 1 :(得分:0)

您可以将数据转换为字典,然后使用dict.get()检索每个索引,以便将值默认为0。

紧凑版:

def fill_missing_with_zero(collection, fill=0.0):
    d = dict(collection)
    return [(key, d.get(key, fill)) for key in [float(i) for i in range(int(max(d))+1)]]

更多细节,如下:

def fill_missing_with_zero(collection, fill=0.0):
    d = dict(collection)
    highest_index = int(max(d.keys()))
    result = []
    for i in range(highest_index+1):
        key = float(i)  # because your "keys" are floats
        result.append((key, d.get(key, fill)))
    return result

示例:

>>> fill_missing_with_zero(collection))
[(0.0, 287999.70000000007),
 (1.0, 161123.23),
 (2.0, 93724.14000000001),
 (3.0, 60347.30999999998),
 (4.0, 55687.24),
 (5.0, 29501.35),
 (6.0, 14993.920000000002),
 (7.0, 14941.970000000001),
 (8.0, 13066.229999999998),
 (9.0, 10101.04),
 (10.0, 4151.6900000000005),
 (11.0, 2998.89),
 (12.0, 1548.93),
 (13.0, 0.0),
 (14.0, 0.0),
 (15.0, 1595.54),
 (16.0, 1435.98),
 (17.0, 1383.01)]

答案 2 :(得分:0)

我稍微修改了你的输入以使用整数值。

假设输入是有序的。首先,我计算出列表中的最高密钥。的顶= in_list [-1] [0]

然后将输入转换为dict。

这意味着如果密钥不存在,我可以使用 get(key [,default])返回零。

然后使用带范围的列表推导来查看可能的整数。需要是top + 1,因为range返回元素的数量,因此从零开始需要一个元素。

list=[(0, 287999.70000000007),
(1, 161123.23000000001),
(2, 93724.140000000014),
(3, 60347.309999999983),
(4, 55687.239999999998),
(5, 29501.349999999999),
(6, 14993.920000000002),
(7, 14941.970000000001),
(8, 13066.229999999998),
(9, 1010140000000001),
(10, 4151.6900000000005),
(11, 2998.8899999999999),
(12, 1548.9300000000001),
(15, 1595.54),
(16, 1435.98),
(17, 1383.01)]

top=in_list[-1][0]
in_dict=dict(in_list)
out_list=[ (i,in_dict.get(i,0)) for i in range(top+1)]
print(out_list)