【问题标题】:How to search list of objects for index of minimum如何在对象列表中搜索最小索引
【发布时间】:2019-07-04 13:46:46
【问题描述】:

我想在对象列表中搜索对象属性中存在的最小数字。

使用列表解析和min 函数很容易。当我想找到对象的索引时,问题就来了。

class School:
    def __init__(self, name, num_pupils, num_classrooms):
        self.name = name
        self.num_pupils = num_pupils
        self.num_classrooms = num_classrooms

    def students_per_class(self):
        return self.num_pupils / self.num_classrooms

    def show_info(self):
        print(f"{self.name} has {self.students_per_class():.2f} students per class.")

    def string_checker(question):
        valid = False
        while not valid:
            try:
                response = str(input(question))
                if all(character.isalpha() or character.isspace() for character in response):
                    valid = True
                    return response
                else:
                    print("Enter a string containing no numbers of special characters. ")
            except ValueError:
                print("Enter a string containing no numbers of special characters. ")

    def num_checker(question):
        valid = False
        while not valid:
            try:
                response = int(input(question))
                if (response):
                    valid = True
                    return response
                else:
                    print("Enter an integer containing no letters or special characters. ")

        except ValueError:
            print("Enter an integer containing no letters or special characters. ")

    def new_school():
        school_name = string_checker("School Name: ")
        num_pupils = num_checker("Number of Pupils: ")
        num_classrooms = num_checker("Number of Classrooms: ")
        return School(school_name, num_pupils, num_classrooms)


if __name__ == "__main__":
    schools = []
    school = School("Darfield High School", 900, 37)
    schools.append(school)
    school.show_info()

    for i in range(1):
        schools.append(new_school())

    for school in schools:
        school.show_info()

    print(min(school.students_per_class() for school in schools)) 
    # This works fine and prints the value of the lowest number
    print(schools.index(min(school.students_per_class() for school in schools))) 
    # This doesn't work as it tries to find the index of the value returned
    # from the min function as it should.

【问题讨论】:

  • 列表和数组在 Python 中是不一样的。你有清单。
  • 你假设最小值是唯一的吗?或返回第一个这样的索引?或者所有这些索引,这意味着结果可以是整数或列表。或包含 1+ 项的列表。

标签: python python-3.x


【解决方案1】:

@Tomas Ordonez

你的答案在这里:

def minInt(instanceList):
    sorted_instanceList = sorted(instanceList, key=lambda instance: instance.int)
    minIndex = instanceList.index(sorted_instanceList[0])
    return minIndex

【讨论】:

  • 这假设最小值是唯一的;否则它返回第一个这样的索引(不是所有这样的索引)。
【解决方案2】:

我想您可能正在寻找np.argmin 函数,如果您提供一个列表作为输入,它将返回最小元素的索引。

在这种情况下是:

import numpy as np 
min_ind = np.argmin([school.students_per_class() for school in schools])
print(schools[min_ind])

【讨论】:

    【解决方案3】:

    如果您希望能够直接比较、排序、查找项目的最小值/最大值,您可以使用“dunder”方法。这些方法允许您重载类的内置函数。

    例如,如果您有这样的课程

    class Item:
        def __init__(self, value):
            self.value = value
    
        def __lt__(self, other):
            return self.value < other.value
    
        def __eq__(self, other):
            return self.value == other.value
    

    然后您可以创建两个实例并像这样直接比较它们,

    A = Item(1)
    B = Item(2)
    
    print(A < B) # Prints True
    

    或者如果你有一个项目列表

    items = [A, B]
    

    然后你可以通过去获得最小的项目

    min_item = min(items)
    

    或者通过去它的索引

    min_item_index = items.index(min(items))
    

    尽管仅引用最小项可能就足够了。

    【讨论】:

      【解决方案4】:

      您可以使用minkey 参数按索引搜索:

      index = min(range(len(schools)), key=lambda i: schools[i].students_per_class())
      print(schools[index])
      

      键提供将被比较的值,而不是实际的序列。在这里,我的序列是range(len(schools)),它只是所有元素的索引。但我没有找到最小索引,而是让我们找到每个索引i 的最小值schools[i].students_per_class()

      【讨论】:

      • 你能推断出 lambda“键”实际上在做什么。谢谢。
      • @Alex。是的,我可以详细说明
      • 我很抱歉我用词不当。能否请您详细说明。谢谢。
      • @Alex。我已经详细说明了
      • @Alex。在某些时候,我们都是初学者。如果你愿意努力,我很乐意提供帮助。
      【解决方案5】:

      使用enumerate 遍历列表,同时跟踪索引:

      min(((i, school.students_per_class()) for i, school in enumerate(schools)), key=lambda x: x[1])
      

      (i, school.students_per_class()) 是一个元组,使用min()key 参数,我们要求Python 找到school.students_per_class() 的最小值,随后返回它的索引。

      了解 lambda here

      【讨论】:

      • 感谢您的回答。您能否解释一下 enumerate 和 lambda 发生了什么?我不知道。再次感谢。编辑:你能把它放在我的上下文中吗?
      • 你需要交换结果元组的顺序,否则总是返回第一项,索引为0。
      • @AlexStiles,我添加了指向官方文档的链接,以便进一步阅读 enumeratelambda
      猜你喜欢
      • 1970-01-01
      • 2012-10-19
      • 2014-10-18
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      相关资源
      最近更新 更多