Самый эффективный способ создания кортежа из списка кортежей - PullRequest
1 голос
/ 01 марта 2020

В настоящее время я использую для l oop с перечислением для извлечения из списка кортежей ниже:

[(0, 'handle', 'VARCHAR(50)', 1, None, 1), (1, 'Firstname', 'TEXT', 1, None, 0), (2, 'Surname', 'TEXT', 1, None, 0), (3, 'Callname', 'TEXT', 1, None, 0), (4, 'Gender', 'INTEGER', 1, None, 0)]

То, что я хочу, это получить следующий кортеж ('handle', 'Firstname', 'Surname', 'Callname', 'Gender')

Какой самый эффективный способ выполнить это, не перечисляя их и не создавая новый кортеж, или это единственный способ?

Ответы [ 3 ]

5 голосов
/ 01 марта 2020

Создайте новый кортеж, перечислив через него:

tuple(t[1] for t in inputlist)

При этом используется выражение генератора для передачи каждого второго элемента из кортежей в inputlist в tuple() конструктор .

Если вам просто нужна последовательность , и список подойдет, используйте понимание списка:

[t[1] for t in inputlist]

Списки соответствуют произвольным Длина, упорядоченные, однородные наборы данных (такие как у вас здесь) лучше, чем у кортежей, см. В чем разница между списками и кортежами?

Если необработанная скорость равна Требуется и читаемость может быть подчеркнуто, используйте map() и operator.itemgetter(), чтобы переместить итерацию и извлечение в оптимизированный C код:

from operator import itemgetter

labels_tup = tuple(map(itemgetter(1), inputlist))
labels_list = list(map(itemgetter(1), inputlist))

Тем не менее, я бы избегал этого, если только извлечение набора строк из списка кортежей не находится на критическом пути и / или не повторяется много раз. Читаемость имеет значение!

без перечисления и создания нового кортежа

Этого нельзя избежать. Вы a) хотите один элемент из каждого кортежа в последовательности, и b) вам нужен объект кортежа в качестве выходного, неизменяемого типа. Несмотря на то, что вы можете написать 5 отдельных операторов, индексирующих в inputlist для доступа к каждому значению, это неэффективно, создает ненужно повторяющийся код и прерывает момент, когда ваш ввод не содержит ровно 5 элементов.

Демо:

>>> inputlist = [(0, 'handle', 'VARCHAR(50)', 1, None, 1), (1, 'Firstname', 'TEXT', 1, None, 0), (2, 'Surname', 'TEXT', 1, None, 0), (3, 'Callname', 'TEXT', 1, None, 0), (4, 'Gender', 'INTEGER', 1, None, 0)]
>>> tuple(t[1] for t in inputlist)
('handle', 'Firstname', 'Surname', 'Callname', 'Gender')
>>> [t[1] for t in inputlist]
['handle', 'Firstname', 'Surname', 'Callname', 'Gender']
2 голосов
/ 01 марта 2020

Вы ищете генератор выражений .

print(tuple(i[1] for i in inputlist))

Или

t = tuple(i[1] for i in inputlist)
print(t)

Выходы:

('handle', 'Firstname', 'Surname', 'Callname', 'Gender')

Возможное решение с for l oop (Не рекомендуется):

li = []
for i in inputlist:
    li.append(i[1])
print(tuple(li))

Какой самый эффективный способ выполнить это, не перечисляя их и не создавая новый кортеж, или это единственный способ?

Я не уверен, почему вы хотите избежать создания кортежа, но вам не нужно перечислять. Может помочь пример, приведенный ниже:

def getElement(ndx):
    return inputlist[ndx][1]

# Get Second Element
print(getElement(2))
1 голос
/ 01 марта 2020
>>> from operator import itemgetter
>>> data = [(0, 'handle', 'VARCHAR(50)', 1, None, 1), (1, 'Firstname', 'TEXT', 1, None, 0), (2, 'Surname', 'TEXT', 1, None, 0), (3, 'Callname', 'TEXT', 1, None, 0), (4, 'Gender', 'INTEGER', 1, None, 0)]
>>> tuple(map(itemgetter(1), data))
('handle', 'Firstname', 'Surname', 'Callname', 'Gender')

Похоже, что это самая быстрая скорость (хотя и незначительно), поскольку она сохраняет все в C как можно больше), и мне тоже нравится этот вид. Конечно, вы все еще просматриваете элементы.

Время:

$ python3 -m timeit -s "data = [(0, 'handle', 'VARCHAR(50)', 1, None, 1), (1, 'Firstname', 'TEXT', 1, None, 0), (2, 'Surname', 'TEXT', 1, None, 0), (3, 'Callname', 'TEXT', 1, None, 0), (4, 'Gender', 'INTEGER', 1, None, 0)]; from operator import itemgetter;" "tuple(map(itemgetter(1), data))"
500000 loops, best of 5: 477 nsec per loop
$ python3 -m timeit -s "data = [(0, 'handle', 'VARCHAR(50)', 1, None, 1), (1, 'Firstname', 'TEXT', 1, None, 0), (2, 'Surname', 'TEXT', 1, None, 0), (3, 'Callname', 'TEXT', 1, None, 0), (4, 'Gender', 'INTEGER', 1, None, 0)]; from operator import itemgetter;" "tuple(t[1] for t in data)"
500000 loops, best of 5: 566 nsec per loop
$ python3 -m timeit -s "data = [(0, 'handle', 'VARCHAR(50)', 1, None, 1), (1, 'Firstname', 'TEXT', 1, None, 0), (2, 'Surname', 'TEXT', 1, None, 0), (3, 'Callname', 'TEXT', 1, None, 0), (4, 'Gender', 'INTEGER', 1, None, 0)]*1000; from operator import itemgetter;" "tuple(map(itemgetter(1), data))"
2000 loops, best of 5: 146 usec per loop
$ python3 -m timeit -s "data = [(0, 'handle', 'VARCHAR(50)', 1, None, 1), (1, 'Firstname', 'TEXT', 1, None, 0), (2, 'Surname', 'TEXT', 1, None, 0), (3, 'Callname', 'TEXT', 1, None, 0), (4, 'Gender', 'INTEGER', 1, None, 0)]*1000; from operator import itemgetter;" "tuple(t[1] for t in data)"
1000 loops, best of 5: 212 usec per loop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...