Как извлечь n-й элемент из списка кортежей в python?
Я пытаюсь получить n-й элемент из списка кортежей.
у меня есть что-то вроде:
elements = [(1,1,1),(2,3,7),(3,5,10)]
Я хочу извлечь только вторые элементы каждого кортежа в список:
seconds = [1, 3, 5]
Я знаю, что это можно сделать с помощью for
петли, но я хотел бы знать, если есть другой способ, так как у меня тысячи записей.
6 ответов:
Я знаю, что это можно сделать с помощью FOR, но я хотел знать, есть ли другой способ
есть и другой способ. Вы также можете сделать это с помощью карта и itemgetter:
>>> from operator import itemgetter >>> map(itemgetter(1), elements)
Это все еще выполняет цикл внутренне, хотя и это немного медленнее, чем понимание списка:
setup = 'elements = [(1,1,1) for _ in range(100000)];from operator import itemgetter' method1 = '[x[1] for x in elements]' method2 = 'map(itemgetter(1), elements)' import timeit t = timeit.Timer(method1, setup) print('Method 1: ' + str(t.timeit(100))) t = timeit.Timer(method2, setup) print('Method 2: ' + str(t.timeit(100)))
результаты:
Method 1: 1.25699996948 Method 2: 1.46600008011Если вам нужно перебирать список, то с помощью
for
- это хорошо.
Это также работает:
zip(*elements)[1]
(Я в основном публикую это, чтобы доказать себе, что я грокнул
zip
...)увидеть его в действии:
>>> help(zip)
справка по встроенной функции zip в модуле builtin:
zip(...)
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
возвращает список кортежей, где каждый кортеж содержит I-й элемент от каждого из последовательности аргументов. Возвращенный список будет усечен от длины до длины самой короткой последовательности аргументов.
>>> elements = [(1,1,1),(2,3,7),(3,5,10)] >>> zip(*elements) [(1, 2, 3), (1, 3, 5), (1, 7, 10)] >>> zip(*elements)[1] (1, 3, 5) >>>
аккуратная вещь, которую я узнал сегодня: используйте
*list
в аргументах для создания списка параметров функции...
нашел это, как я искал, какой путь является самым быстрым, чтобы вытащить второй элемент списка 2-кортежа. Не то, что я хотел, но побежал же тест, как показано с 3-м методом плюс тест zip метод
setup = 'elements = [(1,1) for _ in range(100000)];from operator import itemgetter' method1 = '[x[1] for x in elements]' method2 = 'map(itemgetter(1), elements)' method3 = 'dict(elements).values()' method4 = 'zip(*elements)[1]' import timeit t = timeit.Timer(method1, setup) print('Method 1: ' + str(t.timeit(100))) t = timeit.Timer(method2, setup) print('Method 2: ' + str(t.timeit(100))) t = timeit.Timer(method3, setup) print('Method 3: ' + str(t.timeit(100))) t = timeit.Timer(method4, setup) print('Method 4: ' + str(t.timeit(100))) Method 1: 0.618785858154 Method 2: 0.711684942245 Method 3: 0.298138141632 Method 4: 1.32586884499
Так что более чем в два раза быстрее, если у вас есть 2 кортеж пара просто конвертировать в дикт и принимать значения.
времени Python 3.6 для извлечения второго элемента из списка 2-кортежа.
кроме того, добавил
numpy
метод выбора, который проще читать (но, возможно, проще, чем понимание списка).from operator import itemgetter elements = [(1,1) for _ in range(100000)] %timeit second = [x[1] for x in elements] %timeit second = list(map(itemgetter(1), elements)) %timeit second = dict(elements).values() %timeit second = list(zip(*elements))[1] %timeit second = np.array(elements)[:,1]
и тайминги:
list comprehension: 4.73 ms ± 206 µs per loop list(map): 5.3 ms ± 167 µs per loop dict: 2.25 ms ± 103 µs per loop list(zip) 5.2 ms ± 252 µs per loop numpy array: 28.7 ms ± 1.88 ms per loop
отметим, что
map()
иzip()
больше не возвращайте список, следовательно, явное преобразование.