Если заявление повторить на каждый случай - PullRequest
3 голосов
/ 12 января 2020

У меня есть список с разными названиями курсов, за которыми следует запятая, за которой следует оценка.

courses = ['COMP 1000,A+', "MATH 1000,A+", 'SCIE1000,B+"]

Каждый раз, когда в списке появляется оценка, я меняю ее на значение балла и добавляю это в другой список. Затем я вычисляю средний балл, находя среднее значение. Для этого я использую следующий код:

if any("A+" in n for n in courses):
    grades.append(4.30)
if any("B+" in n for n in courses):
    grades.append(3.30)

Это прекрасно работает для списков, в которых каждый класс повторяется один раз, но для списка курсов, приведенных выше, есть два A +, однако 4.30 добавляется только один раз. Есть ли способ добавить 4,30 в новый список каждый раз, когда оценка в списке?

Спасибо

Ответы [ 5 ]

3 голосов
/ 12 января 2020

Вы идете об этом неправильно. L oop на курсах, разделите их запятыми и найдите преобразование баллов в баллы (эквивалентно выражению case на других языках).

courses = ['COMP 1000,A+', 'MATH 1000,A+', 'SCIE1000,B+']
grades = []

grade_to_grade_point = {
    "A+": 4.30,
    "B+": 3.30,
    # ...
    }
for course in courses:
    course_name, grade = course.split(',')
    grades.append(grade_to_grade_point[grade])

print(grades)  # -> [4.3, 4.3, 3.3]

Или в виде списка:

grades = [grade_to_grade_point[c.split(',')[1]] for c in courses]
2 голосов
/ 12 января 2020

Здесь есть несколько хороших ответов, но никто не говорит вам, почему то, что у вас есть, не работает:

Проблема заключается в том, что вы используете любой . Функция any принимает список логических значений и возвращает true, если хотя бы одно значение в списке истинно.

>>> any([True, True])
True
>>> any([True, False])
True
>>> any([False, False])
False

Независимо от того, сколько True s в списке, возвращается только один логический тип, и ваш оператор if будет выполняться только один раз . Таким образом, даже если в вашем списке есть два «A +», только один append будет сформирован.

Ближайшая вещь к тому, что вы пытаетесь достичь с помощью функции any (что я могу себе представить of) было бы списком со следующим условием:

>>> courses = ['COMP 1000,A+', 'MATH 1000,A+', 'SCIE1000,B+']
>>> [n for n in courses if "A+" in n]
['COMP 1000,A+', 'MATH 1000,A+']

Здесь элементы, не удовлетворяющие условию "A+" in n, не являются частью нового массива. Это заставит ваш код выглядеть так:

for i in [n for n in courses if "A+" in n]:
    grades.append(4.30)

, который говорит, что я бы не рекомендовал делать это . Существуют и другие решения, которые более понятны и удобочитаемы, например Решение Исмила или даже что-то простое:

courses = ["COMP 1000,A+", "MATH 1000,A+", "SCIE1000,B+"]
grades= []
for course in courses:
    if "A+" in course:
       grades.append("4.30")
...

Бонус Pro tip! Рассмотрим вероятность того, что в курсах может быть BIO,A+. который прошел бы оператор if. if "B" in course. Возможно, стоит разделить название курса и оценку.

 >>> "Bio,A+".split(",")
 ['Bio', 'A+']
 >>> "Bio,A+".split(",")[1]
 'A+'

;) happy coding!

1 голос
/ 12 января 2020

Как насчет использования списка ?

courses = ["COMP 1000,A+", "MATH 1000,A+", "SCIE1000,B+"]

def func(x):
    if "A+" in x:
       return 4.30
    elif "B+" in x:
        return 3.30
    # add other cases

grades = [func(x) for x in courses]

print(grades) # [4.3, 4.3, 3.3]
0 голосов
/ 12 января 2020

Существующие ответы великолепны, но я хотел показать более объектно-ориентированный подход на случай, если это будет назидательно. Лично я предпочитаю функциональный стиль, но ОО - это то, чему сейчас учат.

from decimal import Decimal  # for precise decimals instead of float math

class Course:
    def __init__(self, name, lettergrade):
        self.name = name
        self.lettergrade = lettergrade

    @classmethod
    def from_string(cls, s):
        name, lettergrade = s.split(',')
        return cls(name.strip(), lettergrade.strip())

    @property
    def gradepoint(self):
        mapping = {
            "A+": Decimal('4.3'),
            "A": Decimal('4'),
            "A-": Decimal('3.7'),
            "B+": Decimal('3.3'),
            "B": Decimal('3'),
            ... # etc
        }

        return mapping.get(self.lettergrade)

# Read the input into `courses`, then:

courses = [Course.from_string(c) for c in courses]
grades = [c.gradepoint for c in courses]

from statistics import mean

avg = mean(grades)  # gives a Decimal equal to your mean grade
0 голосов
/ 12 января 2020

Если вы хотите, чтобы это было в одной строке, вы можете использовать это:

courses = ['COMP 1000,A+', "MATH 1000,A+", "SCIE1000,B+"]
points = {'A+': 4.30, 'B+': 3.30}
grades = [value for grade, value in points.items() for course in courses if grade in course]
print(grades)

>>> [4.3, 4.3, 3.3]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...