0 Вопрос: Уменьшить размеры многомерного массива в Python [дубликат]

вопрос создан в Thu, May 2, 2019 12:00 AM

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

lst = [[a,b,c], [1,2,3], [x,y,z]]

и я хочу вытащить a, 1 и x и создать отдельный список из них.

Я пытался:

lst2.append(x[0] for x in lst)
    
113
  1. Ваш код почти правильный. Единственная проблема - использование понимания списка.
    2014-07-31 03: 30: 39Z
7 ответов                              7                         

Использование понимания списка :

>>> lst = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [item[0] for item in lst]
>>> lst2
['a', 1, 'x']
    
156
2014-07-31 03: 22: 27Z
  1. Метод понимания списка также является самым быстрым, даже быстрее, чем метод Numpy. В ответе jboi говорится о сравнении производительности,
    2018-07-16 03: 22: 16Z

Вы можете использовать zip:

>>> lst=[[1,2,3],[11,12,13],[21,22,23]]
>>> zip(*lst)[0]
(1, 11, 21)

Или Python 3, где zip не создает список:

>>> list(zip(*lst))[0]
(1, 11, 21)

Или

>>> next(zip(*lst))
(1, 11, 21)

Или (мой любимый) используйте numpy:

>>> import numpy as np
>>> a=np.array([[1,2,3],[11,12,13],[21,22,23]])
>>> a
array([[ 1,  2,  3],
       [11, 12, 13],
       [21, 22, 23]])
>>> a[:,0]
array([ 1, 11, 21])
    
66
2018-01-07 15: 32: 07Z
  1. Могу ли я спросить, почему голосование "за"?
    2017-07-13 19: 49: 39Z
  2. Не проголосовали, но первый фрагмент кода (zip) выдает: «Объект zip не является подписным». Python 3.6 на Jupyter.
    2018-01-07 12: 19: 23Z
  3. @ jboi: сначала просто оберните его вокруг list или используйте next. Спасибо
    2018-01-07 15: 32: 50Z

Python включает функцию под названием itemgetter, которая возвращает элемент по определенному индексу в списке:

from operator import itemgetter

Передайте функции itemgetter () индекс элемента, который вы хотите получить. Чтобы получить первый элемент, вы должны использовать itemgetter (0). Важно понимать, что itemgetter (0) сам возвращает функцию. Если вы передадите список этой функции, вы получите конкретный элемент:

itemgetter(0)([10, 20, 30]) # Returns 10

Это полезно, когда вы комбинируете его с map (), который принимает функцию в качестве первого аргумента, и список (или любой другой итератор) в качестве второго аргумента. Возвращает результат вызова функции для каждого объекта в итерируемой:

my_list = [['a', 'b', 'c'], [1, 2, 3], ['x', 'y', 'z']]
list(map(itemgetter(0), my_list)) # Returns ['a', 1, 'x']

Обратите внимание, что map () возвращает генератор, поэтому результат передается в list () для получения фактического списка. Таким образом, ваша задача может быть выполнена следующим образом:

lst2.append(list(map(itemgetter(0), lst)))

Это альтернативный метод для использования понимания списка, и какой метод выбрать сильно зависит от контекста, читаемости и предпочтений.

Дополнительная информация: https://docs.python.org/3/library/operator.html # operator.itemgetter

    
12
2016-12-04 03: 32: 11Z

У меня была такая же проблема, и она заинтересовалась производительностью каждого решения.

Вот %timeit:

import numpy as np
lst = [['a','b','c'], [1,2,3], ['x','y','z']]

Первый тупой способ преобразования массива:

%timeit list(np.array(lst).T[0])
4.9 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Полностью нативное использование списка (как объяснено @alecxe):

%timeit [item[0] for item in lst]
379 ns ± 23.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Другой родной способ использования zip (как объяснено @dawg):

%timeit list(zip(*lst))[0]
585 ns ± 7.26 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Второй тупой путь. Также объясняется @dawg:

%timeit list(np.array(lst)[:,0])
4.95 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Удивительно (ну, по крайней мере, для меня), родной способ использования списочного понимания самый быстрый и примерно в 10 раз быстрее, чем простой способ. Выполнение двух тупиков без финального list экономит около одного мкс, что все еще в 10-кратной разнице.

Обратите внимание, что когда я окружил каждый фрагмент кода вызовом len, чтобы убедиться, что генераторы работают до конца, время остается неизменным.

    
9
2018-01-08 19: 40: 58Z
  1. существуют значительные издержки при создании массива.
    2018-08-28 03: 12: 50Z
  2. согласен с hpaulj, если вы начинаете с массива numpy, [:, 0] быстрее. Попробуйте: lst = np.array ([['a', 'b', 'c'], [1,2,3], ['x', 'y', 'z']]), затем lst [:, 0]. Преобразование в примерные испытания времени дает понимание списка несправедливое преимущество. Поэтому, если вы можете, используйте массив данных для хранения ваших данных, если ваша конечная цель - скорость. Numpy почти всегда быстрее. Он построен для скорости.
    2018-11-14 20: 13: 12Z

Ваш код почти правильный. Единственная проблема - использование понимания списка.

Если вы используете like: (x [0] для x в lst), он возвращает объект генератора. Если вы используете вроде: [x [0] для x в lst], он возвращает список.

Когда вы добавляете вывод понимания списка в список, вывод понимания списка является единственным элементом списка.

lst = [["a","b","c"], [1,2,3], ["x","y","z"]]
lst2 = []
lst2.append([x[0] for x in lst])
print lst2[0]

lst2 = [['a', 1, 'x']]

lst2 [0] = ['a', 1, 'x']

Пожалуйста, дайте мне знать, если я ошибаюсь.

    
1
2014-07-31 03: 35: 03Z
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
outputlist = []
for values in lst:
    outputlist.append(values[0])

print(outputlist) 

Вывод: ['a', 1, 'x']

    
1
2016-10-25 10: 16: 37Z

Вы сказали, что у вас есть существующий список. Так что я пойду с этим.

>>> lst1 = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [1, 2, 3]

Прямо сейчас вы добавляете объект генератора во второй список.

>>> lst2.append(item[0] for item in lst)
>>> lst2
[1, 2, 3, <generator object <genexpr> at 0xb74b3554>]

Но вы, вероятно, хотите, чтобы это был список первых элементов

>>> lst2.append([item[0] for item in lst])
>>> lst2
[1, 2, 3, ['a', 1, 'x']]

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

>>> lst2.extend(item[0] for item in lst)
>>> lst2
[1, 2, 3, 'a', 1, 'x']

или р>

>>> lst2 + [x[0] for x in lst]
[1, 2, 3, 'a', 1, 'x']
>>> lst2
[1, 2, 3]

https://docs.python.org/3.4/учебник /datastructures.html # более-на-листы https://docs.python.org/3.4/tutorial/datastructures.html # список-постижения

    
0
2014-07-31 03: 51: 18Z
  1. Ваш ответ хорош и полон того, что звучит так, как хочет ОП, но я думаю, что слово append в вопросе вызывает путаницу. Похоже, он /она просто хочет, чтобы часть вашего списка была понятнап.
    2014-07-31 06: 21: 28Z
источник размещен Вот