简体   繁体   中英

Any way to make this easier? Python

This is a python problem where the code was supposed to allow you to input n number of names and scores, and the program would return the name or names of those with the second lowest score. This is what I cam up with and it works perfectly fine but in the interest of getting better I was wondering if there are any simpler ways to accomplish this. My code is below.

n=int(input())
names=[]
for i in range(0,n):
    names.append([input(),float(input())])
for i in range(0,n):
    names[i].reverse()
names.sort()
names.reverse()
misc=[]
for i in range(0,n):
    misc.append(names[i][0])
blank=[]
for i in misc:
    if i not in blank:
        blank.append(i)
blank.reverse()
vals=[]
for i in range(0,n):
    if names[i][0]==blank[1]:
        vals.append(names[i])
vals.reverse()
for i in range(0,len(vals)):
    print(vals[i][1])

First off, the structure could be greatly simplified with dicts.

Start with getting a dict names vs scores. eg:

name_to_score = {
   "alice": 1.2,
   "bob": 1.1,
   "fred": 1.3,
   "nancy": 1.2,
}

Then take that dict and invert it to have a dict of scores vs names:

score_to_names = {
   1.2: ["alice", "nancy"],
   1.1: ["bob"],
   1.3: ["fred"],
}

You can find the second lowest score (key) and print out the values from the inverted dict.

Your implementation could look something like this:

from collections import defaultdict

name_to_score = {}
for _ in range(int(input())):
    name_to_score[input()] = float(input())

score_to_names = defaultdict(list)
for name, score in name_to_score.items():
    score_to_names[score].append(name)

second_lowest_score = sorted(score_to_names.keys())[1]
print(score_to_names[second_lowest_score])

You could also start off by creating the score_to_names dict right away:

from collections import defaultdict

score_to_names = defaultdict(list)
for _ in range(int(input())):
    name = input()
    score = float(input())
    score_to_names[score].append(name)

second_lowest_score = sorted(score_to_names.keys())[1]
print(score_to_names[second_lowest_score])

Your code is hard to read. If you improve readability it will make it easier for you and everybody else to understand what is happening.

The first step would be to split it into 3 parts:

  • Getting input from a user
  • Calculating the result
  • Displaying result to a user

Then I would consider renaming variables. I cannot tell what blank , misc and vals are and why you use reverse() so often.


In pyhton there is build in min() function Built-in Functions .

I would combine it with defaultdict from collections

and used them like this:

from collections import defaultdict

scores_names = defaultdict(list)  # {3:["Johny", "Sanny"], 4:[Ben]}
# Getting input from a user
n = int(input("n:"))
for i in range(0, n):
    scores_names[float(input("score:"))].append(input("name:"))
# Calculating the result
min_score = min(scores_names.keys())
result = scores_names[min_score]
# Displaying result to a user
print(result)

Console:

n:3
score:3
name:Johny
score:3
name:Sanny
score:4
name:Ben
['Johny', 'Sanny']

If you want your code to look nice and follow PEP8 consider using Black

If you want to learn more on how to refactor consider reading this book

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM