我有一个元组列表
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)]