Понимание списка для извлечения нескольких полей из списка кортежей - PullRequest
0 голосов
/ 30 октября 2018

У меня есть список кортежей

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

Я предпочитаю изучать pythonic способ вместо использования цикла - что я делаю неправильно?

Ответы [ 4 ]

0 голосов
/ 30 октября 2018

Использование базового среза, которое дает преимущество в том, что оно не дает сбоя, если любой из ваших элементов списка не имеет ожидаемого количества подэлементов.

[el[:2] for el in servers]

[('server1', 80), ('server2', 443)]
0 голосов
/ 30 октября 2018

Вы можете использовать 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)]
0 голосов
/ 30 октября 2018

То, что вы делали, было почти верно. Вы пытались перевести каждый кортеж из своего списка в новый кортеж. Но вы забыли объявить кортеж. Вот что делают круглые скобки:

hosts = [(x[0], x[1]) for x in servers]
0 голосов
/ 30 октября 2018

Вы можете использовать расширенную повторяемую распаковку .

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

Использование _ в качестве одноименного заполнителя-имени является общим соглашением.

...