簡體   English   中英

如何更改以列表形式輸入for循環的變量

[英]How to change variables fed into a for loop in list form

我正在用Python編寫一個基本程序,提示用戶輸入5個測試分數。 然后程序將每個測試分數轉換為分數點(即4.0,3.0,2.0 ......),然后取這些數字的平均值。

我已經為每個測試分數分配了他們自己的變量,我將它們送入for循環,如下所示:

for num in [score1, score2, score3, score4, score5]:
   if num >= 90
       print('Your test score is a 4.0)
   elif num < 90 and >= 80
   .
   .
   and so on for each grade point.

現在,這可以很好地顯示每個測試分數等同於分數點。 但是,稍后在函數中我需要計算每個等級點值的平均值。 所以,我實際上想要將等級點值分配給當時通過for循環傳遞的特定變量。 因此,當score1通過for循環,並且確定了適當的成績點時,我如何才能將該成績點實際分配給score1,然后將其分配給score2,等等,因為它們通過循環?

我希望這會使問題清楚。 Python本身沒有這種能力似乎很愚蠢,因為如果不是這樣你將無法重新定義通過for循環傳遞的任何變量,如果它是正在傳遞的列表的一部分。

“Python似乎沒有這種能力似乎很愚蠢,因為如果不是這樣你將無法重新定義通過for循環傳遞的任何變量,如果它是正在傳遞的列表的一部分。” - 這就是大多數編程語言的工作方式。 允許這種能力會很糟糕,因為它會產生一種稱為副作用的東西,這會使代碼變得遲鈍。

此外,這是一個常見的編程缺陷,因為您應該使用變量名稱保存數據 :請參閱http://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html (特別是類似問題的列表;即使您沒有處理變量名字,你至少試圖處理變量名稱空間)。 補救措施是在“更高一級”工作:在這種情況下的列表或集合。 這就是你原來的問題不合理的原因。 (某些版本的python會讓你破解locals()字典,但這是不受支持和無證件的行為和非常糟糕的風格。)


但是你可以強制python使用這樣的副作用:

scores = [99.1, 78.3, etc.]
for i,score in enumerate(scores):
    scores[i] = int(score)

以上將在scores數組中將得分降低。 然而, 正確的方法 (除非你正在使用數以億計的元素)是重新創建scores數組,如下所示:

scores = [...]
roundedScores = [int(score) for score in scores]

如果你有很多想做的事情:

scores = [..., ..., ...]

def processScores(scores):
    '''Grades on a curve, where top score = 100%'''
    theTopScore = max(scores)

    def processScore(score, topScore):
        return 100-topScore+score

    newScores = [processScore(s,theTopScore) for s in scores]
    return newScores

旁注:如果你正在進行浮點計算,你應該from __future__ import division或使用python3,或者顯式地轉換為float(...)


如果你真的想修改傳入的內容,可以傳入一個可變對象。 您傳入的數字是不可變對象的實例,但例如,如果您有:

class Score(object):
    def __init__(self, points):
        self.points = points
    def __repr__(self):
        return 'Score({})'.format(self.points)

scores = [Score(i) for i in [99.1, 78.3, ...]]
for s in scores:
    s.points += 5  # adds 5 points to each score

這仍然是一種非功能性的做事方式,因此容易產生副作用引起的所有問題。

第一條規則:當處理一堆類似的項目時, 不要使用一堆命名變量 - 使用數組(列表,集合,字典,最有意義的東西)。

第二條規則:除非你真的要求空間, 否則不要用這種方式覆蓋你的變量 - 你試圖讓一個標簽(變量名)代表兩種不同的東西(原始標記和/或gpa)。 這使調試真的很討厭。

def get_marks():
    marks = []
    while True:
        inp = raw_input("Type in the next mark (just hit <Enter> to quit): ")
        try:
            marks.append(float(inp))
        except ValueError:
            return marks

def gpa(mark):
    if mark >= 90.0:
        return 4.0
    elif mark >= 80.0:
        return 3.0
    elif mark >= 70.0:
        return 2.0
    elif mark >= 60.0:
        return 1.0
    else:
        return 0.0

def average(ls):
    return sum(ls)/len(ls)

def main():
    marks = get_marks()
    grades = [gpa(mark) for mark in marks]

    print("Average mark is {}".format(average(marks)))
    print("Average grade is {}".format(average(grades)))

if __name__=="__main__":
    main()

問題是當你寫這個:

for num in [score1, score2, score3, score4, score5]:

發生的事情是你創建的列表有五個元素,這些元素在你開始迭代時由score1到score5的值定義。 更改其中一個元素不會更改原始變量,因為您已創建包含這些值副本的列表。

如果您運行以下腳本:

score1 = 2
score2 = 3

for num in [score1, score2]:
    num = 1

for num in [score1, score2]:
    print(num)

您將看到更改包含實際變量副本的列表中的每個值實際上並不會更改原始變量的值。 為了更好地理解這一點,您可以考慮查找“按引用傳遞”和“按值傳遞”之間的區別。

對於這個特殊問題,我建議將您希望能夠修改的變量放在列表中,然后迭代該列表而不是包含這些變量副本的列表。

# Take the list of grade as input, assume list is not empty
def convertGrade(myGrades):
    myResult = [] # List that store the new grade
    for grade in myGrades:
        gpa = (grade / 20) -1
        # Depending on how many deciaml you want
        gpa = round(gpa, 1)
        myResult.append(gpa)
    return myResult

# The list of grades, can be more than 5 if you want to
grades = [88.3, 93.6, 50.2, 70.2, 80.5]
convertedGrades = convertGrade(grades)
print(convertedGrades)

total = 0
# If you want the average of them
for grade in convertedGrades:
    total += grade # add each grade into the total

average = total / len(convertedGrades)
print('Average GPA is:', average)

我覺得這可能會做你想要的,這種事情很簡單,所以python會期望你自己寫,我不知道你是不是意味着python應該帶有GPA轉換器功能,你一定可以輕松寫一個。 如果你只想要整數,(我不確定,因為GPA通常帶有小數點),那么你可以使用int(),或者在你追加之前將它四舍五入為0。

輸出:

[3.4, 3.7, 1.5, 2.5, 3.0]
Average GPA is: 2.82

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM