从元组列表中提取多个字段的列表理解



我有一个元组列表

servers = [('server1', 80 , 1, 2), ('server2', 443, 3, 4)]

我想创建一个只有前两个字段的新列表,如:

[('server1', 80), ('server2', 443)]

但我不知道如何为多个元素制作一个列表理解。

hosts = [x[0] for x in servers]  # this works to give me ['server1', server2']
hostswithports = [x[0], x[1] for x in servers] # this does not work

比起使用循环,我更喜欢用蟒蛇的方式学习——我做错了什么?

您可以使用扩展的可迭代解包。

>>> servers = [('server1', 80 , 1, 2), ('server2', 443, 3, 4)]
>>> [(server, port) for server, port, *_ in servers]
[('server1', 80), ('server2', 443)]

使用_作为一次性占位符名称是一种常见的约定。

你所做的几乎是对的。您正试图将列表中的每个元组转换为一个新的元组。但是您忘记了实际声明元组。这就是括号的作用:

hosts = [(x[0], x[1]) for x in servers]

使用基本切片,如果您的任何列表元素没有预期数量的子元素,它的好处是不会失败。

[el[:2] for el in servers]

[('server1', 80), ('server2', 443)]

您可以使用itemgetter:

from operator import itemgetter

servers = [('server1', 80 , 1, 2), ('server2', 443, 3, 4)]
result = list(map(itemgetter(0, 1), servers))
print(result)

输出

[('server1', 80), ('server2', 443)]

更可读的替代方案如下:

from operator import itemgetter
get_server_and_port = itemgetter(0, 1)
servers = [('server1', 80, 1, 2), ('server2', 443, 3, 4)]
result = [get_server_and_port(e) for e in servers]
print(result)  # [('server1', 80), ('server2', 443)]

最新更新