【问题标题】:If in statement problems如果在语句中出现问题
【发布时间】:2020-07-25 08:32:35
【问题描述】:

我正在尝试制定一个计划,该计划是一个课程列表,只有在完成必修课程或在同一学期参加必修课程时才能添加这些课程。

下面我的代码几乎可以工作,但它总是重用这些类,即使它们已经完成/使用。我试图用and (class_list[i][0] not in classes_done) 阻止这种情况,我希望它不会进入 if 语句,但它似乎被忽略了。

这个 if 语句的其余部分似乎工作正常。 (class_list[i][3] == '' or class_list[i][3] in classes_done) 如果是的话,这门课是否有必修课? (class_list[i][2] in classes_for_semester or class_list[i][2] == '')如果是的话,这门课有共修课吗?是在class_for_semester中还是已经完成?

class_list 变量的组织方式如下['name', 'credit', 'co-requisite', 'required completed classes', 'empty']。我将其他变量添加为 cmets 以显示它们的外观。

class PlanGenerator:
def generator(max_credit_allowed, min_credit_allowed, classes_done, class_list):
    classes_for_semester = []
    credits_for_semester = 0
    semester = 0
    full_plan = []
    # class_list = [['MA 241 ', '4', '', '', ''], ['PS 150 ', '3', 'MA 241 ', '', ''], ['UNIV 101', '1', '', '', ''], ['COM 122', '3', '', '', ''], ...]
    # max_credit_allowed = 16
    # min_credit_allowed = 12
    # classes_done=['UNIV 101']
    while len(classes_done) != len(class_list): # keep going until all classes are used
        while int(min_credit_allowed) > credits_for_semester: # keep going until at least the minimum credits are in the semester
            semester += 1
            for i in range(len(class_list)): # looping over the class list
                if int(class_list[i][1]) + credits_for_semester < max_credit_allowed: #if this class was to be added would it go over the max credit for semester if yes go to next class
                    if (class_list[i][3] == '' or class_list[i][3] in classes_done) and (class_list[i][2] in classes_for_semester or class_list[i][2] in classes_done or class_list[i][2] == '') and (class_list[i][0] not in classes_done):
                        classes_for_semester.append(class_list[i][0])
                        credits_for_semester += int(class_list[i][1])
                        print('classes for semester', classes_for_semester)
                        print('semester credits', credits_for_semester)
            classes_done.append(classes_for_semester)
            full_plan.append(semester)
            full_plan.append(classes_for_semester)
            print('full plan', full_plan)
            classes_for_semester = []
            credits_for_semester = 0
    print('done')
    print(full_plan)

我希望我的解释是有道理的。 也许有人可以理解我的错误并帮助我找到一个好的解决方案。 另外,如果您看到任何可以使此代码更简单的内容,请告诉我。

非常感谢

【问题讨论】:

  • 根据您的评论部分(我假设这是此函数的示例输入),while len(classes_done) == len(class_list) 将阻止它运行,因为len(classes_done) 为 1,len(class_list) 为 4+。跨度>
  • 是的,你是对的。我的意思是把!=,现在应该在帖子中修复。

标签: python list for-loop if-statement while-loop


【解决方案1】:

首先,您的while int(min_credit_allowed) &gt; credits_for_semester 行会导致无限循环。需要改成

while len(classes_done) != len(class_list) and int(min_credit_allowed) > credits_for_semester: # Remove the second while loop

其次,您将列表附加到列表中,因此您将获得classes_done 的二维列表 classes_done.append(classes_for_semester)

这应该是

classes_done += classes_for_semester

这样您就可以将classes_for_semester 中的项目添加到classes_done,而不是添加列表。

您的新代码应如下所示:

def generator(max_credit_allowed, min_credit_allowed, classes_done, class_list):
    classes_for_semester = []
    credits_for_semester = 0
    semester = 0
    full_plan = []
    # class_list = [['MA 241 ', '4', '', '', ''], ['PS 150 ', '3', 'MA 241 ', '', ''], ['UNIV 101', '1', '', '', ''], ['COM 122', '3', '', '', ''], ...]
    # max_credit_allowed = 16
    # min_credit_allowed = 12
    # classes_done=['UNIV 101']
    while len(classes_done) != len(class_list) and int(min_credit_allowed) > credits_for_semester: # keep going until at least the minimum credits are in the semester
        semester += 1
        for i in range(len(class_list)): # looping over the class list
            if int(class_list[i][1]) + credits_for_semester < max_credit_allowed: #if this class was to be added would it go over the max credit for semester if yes go to next class
                if (class_list[i][3] == '' or class_list[i][3] in classes_done) and (class_list[i][2] in classes_for_semester or class_list[i][2] in classes_done or class_list[i][2] == '') and (class_list[i][0] not in classes_done):
                    classes_for_semester.append(class_list[i][0])
                    credits_for_semester += int(class_list[i][1])
                    print('classes for semester', classes_for_semester)
                    print('semester credits', credits_for_semester)
        classes_done += classes_for_semester
        full_plan.append(semester)
        full_plan.append(classes_for_semester)
        print('full plan', full_plan)
        classes_for_semester = []
        credits_for_semester = 0
    print('done')
    print(full_plan)

我强烈建议对不存在的值使用None 而不是'',这样您就可以进行简单的value is None 检查,而不是对空字符串进行相等检查。

对于您传入的类信息列表,我会将它们更改为类、字典或命名元组(了解更多关于它们的信息here),以便您可以轻松地通过名称而不是数字来引用值. class_list[i].class_nameclass_list[i]['class_name'] 在未来比魔术索引更容易调试。您甚至可以更改 for 循环以使用实际的类详细信息作为变量,而不是像这样使用 i in range(len(class_list))

for c in class_list:
   if int(c.credits) .... # Using a class or namedtuple approach as suggested above

还有一件小事可能不是一个大问题,但如果这些列表变长可能会成为一个问题:考虑使用sets 而不是lists 来存储classes_doneclasses_for_semester 之类的东西。它还可以防止存储重复项(假设您不想多次存储同一个类)。


要提供namedtuple 建议的具体示例,您可以执行以下操作:

from collections import namedtuple
ClassList = namedtuple('ClassList', ['class_name', 'credits', 'coreq', 'prereq'])

class_list = [
    ClassList(class_name='MA 241', credits=4, coreq=None, prereq=None),
    ClassList(class_name='PS 150', credits=3, coreq='MA 241', prereq=None),
    # ...
]

所以你的 for 循环变成了

for c in class_list:
    if c.credits + credits_for_semester < max_credits_allowed:
        if (c.prereq is None or c.prereq in classes_done) and \
           (c.coreq in classes_for_semester or c.coreq in classes_done or c.coreq is None) and \
           (c.class_name not in classes_done):
            classes_for_semester.append(c.class_name)
            credits_for_semester += c.credits
classes_done += classes_for_semester
full_plan.append(semester)
full_plan.append(classes_for_semester)
classes_for_semester = []
credits_for_semester = 0

【讨论】:

    猜你喜欢
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    相关资源
    最近更新 更多