【问题标题】:How do I use double for loops properly?如何正确使用双循环?
【发布时间】:2019-01-14 18:18:57
【问题描述】:

英国 GSCE 评分系统最近发生了变化,变得令人困惑,它只是不起作用。我只是得到了我的估计成绩,不知道什么是好的,什么不是。为了解决我的困惑,我决定做一些东西来保存、转换和编辑我的成绩。为了使我的代码更整洁,我决定使用两个 for 循环,以便将它们全部打印出来。当我尝试这个时,它看起来像是在工作,但它只是打印了“对于英语,你得到了 6c”,然后当它转到本来应该是英语文学的东西时,它只是打印了“对于英语,你得到了 6c”,我确实得到了6c,但主题不是英语。如果我重新排列 for 循环的顺序,只有成绩相同但课程正常,也会发生同样的情况。

我所做的只是重新安排了 for 循环。似乎没有任何效果。代码如下:

            import time

            with open('lessons.txt', 'r') as f:
                english_language = str(f.readline().strip('\n'))
                english_lit = str(f.readline().strip('\n\n'))
                maths = str(f.readline().strip('\n\n\n'))
                chemistry = str(f.readline().strip('\n\n\n\n'))
                physics = str(f.readline().strip('\n\n\n\n\n'))
                biology = str(f.readline().strip('\n\n\n\n\n\n'))
                re = str(f.readline().strip('\n\n\n\n\n\n\n'))
                business = str(f.readline().strip('\n\n\n\n\n\n\n\n'))
                computer_science = str(f.readline().strip('\n\n\n\n\n\n\n\n\n'))
                french = str(f.readline().strip('\n\n\n\n\n\n\n\n\n\n'))
                geography = str(f.readline().strip('\n\n\n\n\n\n\n\n\n\n\n'))

            lessons = []
            lessons.extend((english_language, english_lit, maths, chemistry, physics, biology, re, business, computer_science, french, geography))
            lesson_name = ["English langauge", "English liturature", "Maths", "Chemistry", "Physics", "Biology", "R.E", "Business studies", "Computer science", "French", "Geography"]

            print("What do you want to do? Read your grades, edit your grades, convert your grades or read and convert your grades.")
            option = input("Say read to read your grades or edit to edit your grades: ")

            if option == "read":
                for i in lessons:
                    for name in lesson_name:
                        print("For", name, "you got",i)
                        time.sleep(3)
                        break

            elif option == "convert":
                import converter.py

            elif option == "edit":
                print("HIIIIIIIIIIIIIIIIIIII")

文件中的成绩从我得到的最低的 5B 到我得到的最高的 7B。

我期望它做的是问你想做什么,它会做什么。然后,如果您输入“阅读”,它将显示“对于英语,您获得了 6c”并重复,直到进入地理。

【问题讨论】:

  • 您的阅读代码看起来很奇怪。 .strip('\n\n\n\n\n\n\n\n\n\n\n')

标签: python-3.x loops for-loop


【解决方案1】:

两个 for 循环没有意义 - break 也很奇怪:

for i in lessons:
    for name in lesson_name:
        print("For", name, "you got",i)
        time.sleep(3)     # 
        break             # this breaks after the first name every time

您可以使用类似的方式一次迭代两个列表:

nums = [1,2,3]
for idx,value in enumerate(["A","B","C"]):
     print("For", value, "you got", nums[idx])

或通过压缩更好 - 请参阅下面的固定数据解析和后处理。


您可以通过忽略换行来大大简化您的阅读,然后使用zip() 将剩余的成绩转换为字典:

创建一个包含换行符(以及太多值)的文件

import random

gr = [ f'{num}{let}' for num in range(1,10) for let in "ABC"]

with open('lessons.txt', 'w') as f:
    for k in random.choices(gr,k=20):
        f.write(k+"\n\n\n")

读取文件并分解列表

with open('lessons.txt', 'r') as f:
    # read all lines, remove newlines, create a list of results
    grades = [x.strip() for x in f.readlines() if x.strip()]

# there are 20 scores in the file *_ takes all that are not named decomps: 

english_language, english_lit, maths, chemistry, physics, biology, re, \
business, computer_science, french, geography, *remainder = grades

print(english_language, english_lit, maths, chemistry, physics, biology, re, \
      business, computer_science, french, geography )

输出(3 次运行):

3C 6A 9B 7B 8B 5A 2B 8C 7B 3A 9B
1C 8A 5A 1C 3A 9B 7C 9A 7B 7A 1A
4C 1A 4C 8B 9A 3C 2C 7B 7C 5B 2A

为课程和成绩创建一个查找字典:

您可以使用zip() 将成绩与lesson_name 联系起来:

# order the same as in the 
lesson_name = ["English langauge", "English liturature", "Maths", "Chemistry",
               "Physics", "Biology", "R.E", "Business studies", "Computer science", 
               "French", "Geography", "Remainder"]

# dict comprehension to build the dictionary mapping lesson names to grades
grades = {k:v for k,v in zip(
    lesson_name,
    [english_language, english_lit, maths, chemistry, physics, biology, re,  
     business, computer_science, french, geography, remainder])}

print (grades) 

输出:

{'English langauge': '4B', 'English liturature': '3C', 'Maths': '1C', 
 'Chemistry': '8C', 'Physics': '6B', 'Biology': '2B', 'R.E': '6C',
 'Business studies': '8C', 'Computer science': '4B', 'French': '3A', 
 'Geography': '2A', 
 'Remainder': ['7B', '1A', '1C', '3B', '2B', '8B', '5B', '6B', '8C']}

您可以使用 dict 按名称查找成绩:

print(grades["English langauge"]) # 4B

打印所有东西:

for name, grade in grades.items():
    print("For", name, "you got", grade) 
    # do not break here- this will end the loop!

一些解释:

grades = [x.strip() for x in f.readlines() if x.strip()]

整个列表 comp 读取文件的所有行,丢弃空行和仅包含空格(空格、制表符、换行符、..)的行 - 剩余的行被放入列表 grades 但首先被剥离所以没有任何开始/结束空格。

  • zip() 接受多个迭代并将它们配对成元组 - 只要最短的迭代是:

k = zip( [1,2,3],["a","b"],"!$&(=" )  #  [(1, 'a', '!'), (2, 'b', '$')]

结果:

(1, 'a', '!')   # every 0th element
(2, 'b', '$')   # every 1st element and nothing more because ["a","b"] has no 2nd element

将此应用于您的数据,我将您的单个成绩列表和lecture_names 的“字符串”压缩在一起以获得:

[('English langauge', '5B'), ('English liturature', '8B'), ('Maths', '1C'), 
 ('Chemistry', '4B'), ('Physics', '4C'), ('Biology', '9A'), ('R.E', '6B'), 
 ('Business studies', '8A'), ('Computer science', '1A'), ('French', '8C'), 
 ('Geography', '9B'), 

 ('Remainder', ['7A', '4C', '6C', '5B', '3B', '9C', '3B', '1A', '3B'])]

并在 dict-comprehension 中使用它来创建字典:

grades = {k:v for k,v in zip(
    lesson_name,
    [english_language, english_lit, maths, chemistry, physics, biology, re,  
     business, computer_science, french, geography, remainder])}

kv 是一个 zip-result-tuple 的分解 - dict 理解从它们创建一个字典:

ex = {k:v for k,v in [ ("a",1), ("b",2) ] }  # simplified example

返回 ex 作为字典 {"a":1, "b":2}

HTH

【讨论】:

  • 非常感谢!这工作得很好,只是喜欢我想要的。我已经对其进行了一些编辑,因此它不会选择随机等级和其余部分。但除此之外,它工作正常。你介意解释一下,这样我就可以理解代码的作用了吗?如果不是那也没关系。
  • 我不知道,但可能是因为你没有回答问题,而是用全新的代码解决了问题?
猜你喜欢
  • 2021-10-19
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 2016-05-11
  • 2020-12-05
  • 2016-04-10
相关资源
最近更新 更多