【问题标题】:Python - sorting a list of numbers based on indexesPython - 根据索引对数字列表进行排序
【发布时间】:2018-07-08 03:13:45
【问题描述】:

我需要创建一个程序,该程序具有一个创建对象“Food”的类和一个名为“fridge”的列表,该列表保存由类“Food”创建的这些对象。

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),]

这并不难。然后我创建了一个函数,它可以为您提供具有最高保质期的食物。

def exp(fridge):
    expList=[]
    xen = 0
    for i in range(0,len(fridge)):
        expList.append(fridge[xen].expiration)
        xen += 1
    print(expList)
    sortedList = sorted(expList)
    return sortedList.pop()

exp(fridge)

这个也可以,现在我必须创建一个函数来返回一个列表,其中列表的索引是到期日期,该索引的编号是具有该到期日期的食物数量。 输出应如下所示: [0,2,1,1] - 第一个索引 0 表示没有过期日期为“0”的食物。索引 1 表示有 2 件食品的保质期为 1。以此类推。我被太多的 if 行卡住了,我根本无法让它工作。我应该如何处理这个?感谢您的帮助。

【问题讨论】:

  • is expList 是每件商品的有效期吗?从那个列表中,你想要你提到的 o/p 吗?
  • 你能提到你得到的第一个 o/ps 和你接下来需要的确切 o/p 吗?
  • 我的问题已经在下面的 cmets 中得到解答。感谢您的兴趣。 expList 是每一项的有效期,是的。

标签: python list class sorting


【解决方案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]

【讨论】:

  • 非常感谢您的回答。您能否再描述一下您的功能?即使在调试器中,我也很难理解它。谢谢:)
  • 当然,max(food.expiration for food in fridge) 将遍历冰箱中的食物,查看过期时间并返回遇到的最大过期次数。在您的示例中,这将是 4。在您的示例中,您想要返回一个长度为 5 的列表,您想要显示返回 0、1、2、3 和 4 的频率(因此是 +1)。然后使用[0] * max_expiration 行启动一个包含5 个零的列表。然后您遍历冰箱中的食物并相应地更新与过期日期匹配的索引。
  • 非常感谢。现在我明白了:)
【解决方案2】:

您可以迭代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

【讨论】:

    【解决方案3】:

    您可以使用itertools.groupby 创建一个dict,其中key 是食物的过期日期,value 是它在列表中出现的次数

    >>> 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 的所有元素进行分组(注意 groupby 中的key 参数)。 groupby 操作的输出大致相当于(k,[v]),其中k 是组键,[v] 是属于该特定组的值列表。

    这将产生如下输出:

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

    此时我们有expiration 和列表中特定过期发生的次数,存储在字典d 中。

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

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

    这将产生您所需的输出

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

    【讨论】:

      【解决方案4】:

      这是使用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}
      

      【讨论】:

        【解决方案5】:

        用 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
        

        【讨论】:

        • 感谢您的回答。您能否解释一下,您的代码是如何工作的?
        • 我发现如果有效期的最大值大于冰箱的长度是错误的。所以我把它从range(0, len(fridge)+1)修改为range(0, max(exp_list)+1 )
        • 无论如何,创建一个所有过期的列表,并从0迭代到最大过期。 count() 是一个对列表中特定项目进行计数的函数,因此在循环中它将按顺序将过期计数附加到输出列表中,output[0] = exp_list.count(0) 等等。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-28
        • 2020-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多