Python - 根据索引对数字列表进行排序

时间:2018-01-29 12:13:41

标签: python list class sorting

我需要创建一个程序,其中包含一个包含对象“Food”的类和一个名为“refrigerator”的列表,其中包含由“Food”类创建的这些对象。

import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np; np.random.seed(9)

x = np.random.rayleigh(size=9900)
y = np.random.rayleigh(size=9900)

M, xe, ye = np.histogram2d(x, y, bins = 80)

extent = [xe[0], xe[-1], ye[0], ye[-1]]
plt.imshow(M.T, extent=extent, norm = LogNorm(), origin="lower")

plt.show()

这并不难。然后我创建了一个函数,它为您提供最高到期数量的食物。

class Food:
    def __init__(self, name, expiration):
        self.name = name
        self.expiration = expiration


fridge = [Food("beer",4), Food("steak",1),  Food("hamburger",1),  Food("donut",3),]

这个也有效,现在我必须创建一个函数,该函数返回一个列表,其中列表的索引是到期日期,该索引的数量是具有该到期日期的食物的数量。 输出应如下所示:[0,2,1,1] - 第一个索引0表示没有有效期限为“0”的食物。指数1表示有2件食品剩余有效期1.依此类推。我陷入了太多的线条,我不能让这一个工作。我该怎么办呢?谢谢你的帮助。

5 个答案:

答案 0 :(得分:1)

您可以迭代Food个对象列表并更新到期时键入的字典,其值为具有该过期的项目数。避免冗余,例如使用collections.Counter对象(dict的子类)在列表中保持零计数:

from collections import Counter

d = Counter(food.expiration for food in fridge)
# fetch number of food with expiration 0
print(d[0]) # -> 0
# fetch number of food with expiration 1
print(d[1]) # -> 2

答案 1 :(得分:1)

为了将其作为列表返回,您首先需要确定冰箱中的最大到期日期。

max_expiration = max(food.expiration for food in fridge) +1 # need +1 since 0 is also a possible expiration
exp_list = [0] * max_expiration
for food in fridge:
    exp_list[food.expiration] += 1
print(exp_list)

返回[0, 2, 0, 1, 1]

答案 2 :(得分:1)

您可以使用itertools.groupby创建dict,其中密钥将是食物到期日期,值将是其在列表中出现的次数

>>> from itertools import groupby
>>> fridge = [Food("beer",4), Food("steak",1),  Food("hamburger",1),  Food("donut",3),]
>>> d = dict((k,len(list(v))) for k,v in groupby(sorted(l,key=lambda x: x.expiration), key=lambda x: x.expiration))

在此,我们指定groupby对列表中具有相同expiration的所有元素进行分组(注意 key中的groupby参数)。 groupby操作的输出大致相当于(k,[v]),其中k是组密钥,[v]是属于该特定组的值列表。

这将产生如下输出:

>>> d
>>> {1: 2, 3: 1, 4: 1}

此时我们有expiration次列出的特定过期次数,存储在dict d中。

接下来我们需要创建一个列表,如果dict d中存在一个元素,则输出它,否则输出0。我们需要在dict d键中从0到最大数字迭代。为此,我们可以这样做:

>>> [0 if not d.get(x) else d.get(x) for x in range(0, max(d.keys())+1)]

这将产生您所需的输出

>>> [0,2,0,1,1]

答案 3 :(得分:0)

以下是使用collections.defaultdict的灵活方法:

from collections import defaultdict

def ReverseDictionary(input_dict):
    reversed_dict = defaultdict(set)
    for k, v in input_dict.items():
        reversed_dict[v].add(k)
    return reversed_dict

fridge_dict = {f.name: f.expiration for f in fridge}

exp_food = ReverseDictionary(fridge_dict)
# defaultdict(set, {1: {'hamburger', 'steak'}, 3: {'donut'}, 4: {'beer'}})

exp_count = {k: len(exp_food.get(k, set())) for k in range(max(exp_food)+1)}
# {0: 0, 1: 2, 2: 0, 3: 1, 4: 1}

答案 4 :(得分:0)

使用count()修改你的。

def exp(fridge):
    output = []
    exp_list = [i.expiration for i in fridge]
    for i in range(0, max(exp_list)+1):
        output.append(exp_list.count(i))
    return output