繁体   English   中英

列表理解以过滤列表列表

[英]list comprehension to filter a list of lists

这个问题来自https://leetcode.com/problems/find-players-with-zero-or-one-losses/ 是否可以在此问题中使用列表理解来创建一个新列表,该列表仅包含每个元组的第一项,而永远不会出现在任何元组的第二项中。

例如:

matches = [[1,3],[2,3],[3,6],[5,6],[5,7],[4,5],[4,8],[4,9],[10,4],[10,9]]

我想要一个新列表:

neverLost = [1, 2, 10]

我会制作两个列表,一个用于问题的每个部分和列表理解,然后将它们连接在一起以获得解决方案。 我尝试使用列表理解,但遇到语法问题

neverLost = [w for w, l in matches if w not l]

w for w, l in matches的第一部分 w 工作正常,将创建一个仅包含每个元组[1, 2, 3, 5, 5, 4, 4, 4, 10, 10]第一项的列表,但我'我在语法和对表达式的理解上苦苦挣扎,以过滤“赢家”。 请让我知道这是否是解决问题的好方法。 我知道我可能可以用字典来做到这一点,但我想知道这种方式是否也可行。 谢谢!

列表理解有效,但不是解决此类问题的优化方法

In [48]: list(set([j[0] for j in matches if j[0] not in [i[1] for i in matches]]))
Out[48]: [1, 2, 10]

你做了什么

neverLost = [w for w, l in matches if w not l]

将检查该元组中的第一项是否等于同一元组中的第二项。 检查第一项是否存在于任何其他元组中的第二个 position。

你可以用这个 -

list(set([w[0] for w in matches if w[0] not in [l[1] for l in matches]]))

我认为你需要做类似的事情,

matches = [[1, 3], [2, 3], [3, 6], [5, 6], [5, 7], [4, 5], [4, 8], [4, 9], [10, 4], [10, 9]]

losses_dict = {}
for (_, value) in matches:
    losses_dict.setdefault(value, 0)  # key might exist already
    losses_dict[value] += 1

final_list = [
              [k for k, _ in matches if k not in losses_dict.keys()],
              [k for k, v in losses_dict.items() if v == 1]
             ]

dict.setdefault 检查键是否已经存在,否则它附加值 0。

当然,这样的事情是一个合理的解决方案:

seconds = {second for _, second in matches}
never_lost = [first for first, _ in matches if first not in seconds]
never_lost = list(dict.fromkeys(never_lost))  # idiom for removing duplicates while maintaining order

现在,如果你的意思是只使用一个列表理解表达式,那么你必须变得非常笨拙:

never_lost = [
    x for x in
    {
        first: None
        for first, _ in matches 
        for seconds in [{second for _, second in matches}] 
        if first not in seconds
    }
]

我会坚持第一种方法。 并非所有内容都必须或应该是单个列表理解表达式。

neverLost = list(set(w for w, l in matches if all(w != j for i, j in matches)))

列表理解对性能有好处,但大多数时候复杂的列表理解会降低代码的可读性。

另一种方法是将 model 问题作为有向图,其中每个玩家都是图的一个顶点,边决定比赛的结果,这样边的方向就是从赢家到输家。

例如。

[1, 2] => [1](赢家) -> [2](输家)

现在问题归结为计算顶点的入度/出度,这应该会给我们想要的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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