Каков самый быстрый и элегантный способ составления списков из двух списков?
у меня есть
In [1]: a=[1,2,3,4,5,6]
In [2]: b=[7,8,9,10,11,12]
In [3]: zip(a,b)
Out[3]: [(1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12)]
И я бы хотел иметь
In [3]: some_method(a,b)
Out[3]: [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]]
Я думал об использовании карты вместо zip, но я не знаю, есть ли какой-нибудь стандартный библиотечный метод, который можно было бы использовать в качестве первого аргумента.
Я могу определить для этого свою собственную функцию и использовать карту, мой вопрос в том, что уже реализовано. Нет - тоже ответ.
Ответы:
Если вы архивируете более 2 списков (или даже только 2, если на то пошло), удобочитаемым способом будет:
[list(a) for a in zip([1,2,3], [4,5,6], [7,8,9])]
Это использует понимание списка и преобразует каждый элемент в списке (кортежи) в списки.
источник
Вы сами почти получили ответ. Не используйте
map
вместоzip
. Использованиеmap
ANDzip
.Вы можете использовать карту вместе с zip для элегантного и функционального подхода:
zip
возвращает список кортежей.map(list, [...])
вызываетlist
каждый кортеж в списке.list(map([...])
превращает объект карты в читаемый список.источник
generator
к тому, что здесь стоит двойная стоимостьlist
.Мне нравится элегантность функции zip, но использование функции itemgetter () в модуле оператора кажется намного быстрее. Я написал простой скрипт, чтобы проверить это:
import time from operator import itemgetter list1 = list() list2 = list() origlist = list() for i in range (1,5000000): t = (i, 2*i) origlist.append(t) print "Using zip" starttime = time.time() list1, list2 = map(list, zip(*origlist)) elapsed = time.time()-starttime print elapsed print "Using itemgetter" starttime = time.time() list1 = map(itemgetter(0),origlist) list2 = map(itemgetter(1),origlist) elapsed = time.time()-starttime print elapsed
Я ожидал, что zip будет быстрее, но метод itemgetter явно выигрывает:
Using zip 6.1550450325 Using itemgetter 0.768098831177
источник
zip
создает реальный список. Это замедляет работу. Попробуйте заменитьzip
наitertools.izip
then.list1 = [x[0] for x in origlist]
работает так же хорошоlist1 = map(itemgetter(0), origlist)
.Я вообще не люблю лямбда, но ...
>>> a = [1, 2, 3, 4, 5] >>> b = [6, 7, 8, 9, 10] >>> c = lambda a, b: [list(c) for c in zip(a, b)] >>> c(a, b) [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]
Если вам нужна дополнительная скорость, карта будет немного быстрее:
>>> d = lambda a, b: map(list, zip(a, b)) >>> d(a, b) [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]
Однако карта считается не питонной и должна использоваться только для настройки производительности.
источник
lambda
здесь добавить? Можно просто написать выражение вместо вызова функции (это действительно несложно), и даже если кому-то нужна функция для нее, ее можно безболезненно определить в двух строках (одна, если ваш ключ возврата сломан или вы сошли с ума) .map
с другой стороны, совершенно нормально, если бы первым аргументом была простая функция (в отличие от alambda
).map
болееlambda
. так чтоmap(list, zip(a,b))
. Понимание списка может быть немного яснее, но карта должна быть быстрее (непроверено)Как насчет этого?
>>> def list_(*args): return list(args) >>> map(list_, range(5), range(9,4,-1)) [[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]]
Или даже лучше:
>>> def zip_(*args): return map(list_, *args) >>> zip_(range(5), range(9,4,-1)) [[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]]
источник
Использование numpy
Определение элегантности может быть довольно сомнительным, но если вы работаете с
numpy
созданием массива и его преобразованием в список (при необходимости ...), это может быть очень практичным, хотя и не таким эффективным по сравнению с использованиемmap
функции или понимания списка.import numpy as np a = b = range(10) zipped = zip(a,b) result = np.array(zipped).tolist() Out: [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]
В противном случае, пропуская
zip
функцию, которую вы можете использовать напрямуюnp.dstack
:np.dstack((a,b))[0].tolist()
источник
Думаю, понимание списка было бы очень простым решением.
a=[1,2,3,4,5,6] b=[7,8,9,10,11,12] x = [[i, j] for i, j in zip(a,b)] print(x) output : [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]]
источник