HackerRank: Nested Lists 笔记和题解
HackerRank Nested Lists 题解以及 Python Set 和Python Generator 的一些性质解释。Python Iterator 和 Iterable 的区别在哪。Nested Lists 题目:“Given the names and grades for each student in a class of $N$ students, store them in a nested list and print the name(s) of any student(s) having the second lowest grade...”
Table of Contents
题目
这一题我第一遍虽然过了,但是写出来的答案感觉不够短,也没有用到 List Comprehension,虽然可读性应该是比较高。
于是我就再写了一个有 List Comprehension 的版本,也发现了几个小问题。
笔记
Python Set 并不 Preserve Order
如果要移除一个 list 的 duplicates 并 sort 的话,应该要先 set 再 sort,比如:
l = [3,2,4,4,5]
l = sorted(set(l))
print(l)
#输出:[2, 3, 4, 5]
我一开始想着先 sort 再 set,比如:
l = [3,2,4,4,5]
l = set(sorted(l))
print(l)
#输出:{2, 3, 4, 5}
这样做是假设了 set 会 preserve order,比如 set([2,3,4,5])
会是 {2,3,4,5}
,对 [2,3,4,5]
倒是的确可以。
但比如我们换一个:
l = [32,36,39,40]
l = set(sorted(l))
print(l)
#输出:{32, 40, 36, 39}
这样就不行了,原因就在于 set 底层是用 Hash Table 实现的。所以不一定保持原本的 order,即便没有做额外的 insertion。
Python Generator
在做这道题的过程中,我发现了另一个问题:
print(sorted(x for x in range(10)))
print(sorted([x for x in range(10)]))
# 输出:
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
这里的 sorted() 里面加不加[ ]都可以。我向来是习惯写第二种的,这道题也是,但是看答案发现它用了第一种写法。
我就仔细研究了一下,发现:
print(x for x in range(10))
print([x for x in range(10)])
# 输出:
# at 0x0000024C98D7DC10>
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
于是为了理解 Generator Object,我又看了以下三篇文章:
简单来说,就是 Generator Object 可以简化代码以及提升 Performance,因为它不存储数值,相当于一次算一个。但是 Generator 也只能用一次。不能 for loop 第二次。具体的可以再看这三篇里面举的各种例子。
Python Iterator 和 Iterable
当然为了搞清楚 Generator,可能也需要先明白 Python 的 Iterator 和 Iterable。我找到了两张非常好的图:
这两张图的来源应该是:
题解
if __name__ == '__main__':
l = []
for _ in range(int(input())):
name = input()
score = float(input())
l.append([name,score])
score = sorted(set([x[1] for x in l]))[1]
result = [x[0] for x in sorted(l, key = (lambda y: y[0])) if x[1] == score]
print("\n".join(result))
然的博客 Newsletter
Join the newsletter to receive the latest updates in your inbox.