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

题目

Nested Lists | HackerRank
In a classroom of N students, find the student with the second lowest grade.

这一题我第一遍虽然过了,但是写出来的答案感觉不够短,也没有用到 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,我又看了以下三篇文章:

Generators - Python Wiki
What does the “yield” keyword do in Python?
What is the use of the yield keyword in Python? What does it do?For example, I’m trying to understand this code1:def _get_child_candidates(self, distance, min_dist, max_dist): if self._leftch…
python生成器到底有什么优点? - 知乎
例如:用[]推导出来的列表和()推导出来的生成器,在用for循环打印时,有什么不同吗?哪个环节不一样?

简单来说,就是 Generator Object 可以简化代码以及提升 Performance,因为它不存储数值,相当于一次算一个。但是 Generator 也只能用一次。不能 for loop 第二次。具体的可以再看这三篇里面举的各种例子。

Python Iterator 和 Iterable

当然为了搞清楚 Generator,可能也需要先明白 Python 的 Iterator 和 Iterable。我找到了两张非常好的图:

这两张图的来源应该是:

Iterables vs. Iterators vs. Generators
A little pocket reference on iterables, iterators and generators.

题解

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))
HackerRank简单难度算法算法竞赛

Comments