Как создать объект типа списка в Python с установленным размером? [Дубликат]

Теперь класс FirebaseOptions, взятый из других зависимостей, можно удалить компоненты firebase из других зависимостей, как показано ниже, используя тег exclude.

compile 'com.google.firebase:firebase-admin:5.8.0' 

compile ('com.google.firebase:firebase-messaging:9.6.1'){
    exclude module: 'firebase-common'
}
compile ('com.google.firebase:firebase-auth:9.6.1'){
    exclude module: 'firebase-common'
}
compile ('com.google.firebase:firebase-database:9.6.1'){
    exclude module: 'firebase-common'
}
compile ('com.firebase:firebase-client-android:2.5.0'){
    exclude module: 'firebase-common'
}
27
задан jamylak 16 May 2012 в 12:01
поделиться

7 ответов

(tl; dr: Точный ответ на ваш вопрос - numpy.empty или numpy.empty_like, но вам, вероятно, все равно, и вы можете избежать использования myList = [None]*10000.)

Простые методы

Вы можете инициализировать свой список всем тем же элементом. Является ли это семантически целесообразным использовать нечисловое значение (это даст ошибку позже, если вы его используете, что хорошо) или что-то вроде 0 (необычно? Может быть, полезно, если вы пишете разреженную матрицу или « значение по умолчанию должно быть 0, и вы не беспокоитесь об ошибках) зависит от вас:

>>> [None for _ in range(10)]
[None, None, None, None, None, None, None, None, None, None]

(Здесь _ - это просто имя переменной, вы могли бы использовать i.)

Вы также можете сделать это следующим образом:

>>> [None]*10
[None, None, None, None, None, None, None, None, None, None]

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

>>> x = []
>>> for i in range(10):
>>>    x.append(i)

Сравнение производительности простых методов

Что лучше?

>>> def initAndWrite_test():
...  x = [None]*10000
...  for i in range(10000):
...   x[i] = i
... 
>>> def initAndWrite2_test():
...  x = [None for _ in range(10000)]
...  for i in range(10000):
...   x[i] = i
... 
>>> def appendWrite_test():
...  x = []
...  for i in range(10000):
...   x.append(i)

Результаты в python2.7:

>>> import timeit
>>> for f in [initAndWrite_test, initAndWrite2_test, appendWrite_test]:
...  print('{} takes {} usec/loop'.format(f.__name__, timeit.timeit(f, number=1000)*1000))
... 
initAndWrite_test takes 714.596033096 usec/loop
initAndWrite2_test takes 981.526136398 usec/loop
appendWrite_test takes 908.597946167 usec/loop

Результаты в python 3.2:

initAndWrite_test takes 641.3581371307373 usec/loop
initAndWrite2_test takes 1033.6499214172363 usec/loop
appendWrite_test takes 895.9040641784668 usec/loop

Как мы видим, лучше всего сделать идиому [None]*10000 в как python2, так и python3. Однако, если вы делаете что-то более сложное, чем назначение (например, что-то сложное для создания или обработки каждого элемента в списке), тогда накладные расходы становятся бессмысленно малой частью стоимости. То есть такая оптимизация преждевременна, чтобы беспокоиться о том, что вы делаете что-то разумное с элементами вашего списка.


Неинициализированная память

Все это, однако, неэффективно, потому что они пройти через память, написать что-то в этом процессе. В C это другое: неинициализированный массив заполнен случайной памятью мусора (sidenote: это было перераспределено из системы и может быть угрозой безопасности , когда вы выделяете или не выполняете попытку mlock и / или не выполняете для удаления памяти при закрытии программы). Это выбор дизайна, предназначенный для ускорения: разработчики языка C считали, что лучше не автоматически инициализировать память, и это был правильный выбор.

Это не асимптотическое ускорение (потому что это O(N)), но, например, вам не нужно будет сначала инициализировать весь блок памяти, прежде чем перезаписывать все, что вам действительно нужно. Это, если это было возможно, эквивалентно чему-то вроде (псевдокода) x = list(size=10000).

Если вы хотите что-то подобное в python, вы можете использовать числовую матрицу numpy / N-мерно- массив манипулирования массивом. В частности, numpy.empty или numpy.empty_like

Это реальный ответ на ваш вопрос.

37
ответ дан Community 21 August 2018 в 18:40
поделиться
  • 1
    _ является просто "тупой" имя переменной, которая не нужна при повторении диапазона? Мне хотелось бы, чтобы просто for range(10) можно было писать иногда. – Ray Koopa 21 May 2016 в 12:49
  • 2
    x = [[None]]*10 является «неправильным». Попробуйте x[0].append(1) и увидите волшебство. – Amit Tripathi 3 June 2016 в 08:04
  • 3
    @ Death-Stalker: да, я думаю, это то, что я на самом деле пытался указать и проиллюстрировать («работа с изменчивыми объектами»). Но спасибо, я думаю, вы заставили меня понять, что мой ответ ужасно сформулирован. Исправлена. – ninjagecko 3 June 2016 в 10:51
  • 4
    как насчет xrange? – Trinh Hoang Nhu 16 August 2017 в 17:05

На самом деле это не путинский способ инициализации списков. В любом случае, вы можете инициализировать список следующим образом:

>>> l = [None] * 4
>>> l
[None, None, None, None]
3
ответ дан BluePeppers 21 August 2018 в 18:40
поделиться
your_list = [None]*size_required
1
ответ дан cobie 21 August 2018 в 18:40
поделиться

Вы можете использовать это: [None] * 10. Но это не будет «фиксированный размер», который вы все еще можете добавить, удалить ... Вот как делаются списки.

Вы можете сделать его кортежем (tuple([None] * 10)), чтобы исправить его ширину, но опять же, вы не сможете его изменить (не во всех случаях, только если сохраненные элементы изменяются).

Другой вариант, ближе к вашему требованию, не является списком, а collections.deque с максимальной длиной. Это максимальный размер, но он может быть меньше.

import collections
max_4_items = collections.deque([None] * 4, maxlen=4)

Но просто используйте список и привыкните к «питоническому» способу делать вещи.

7
ответ дан jadkik94 21 August 2018 в 18:40
поделиться
fix_array = numpy.empty(n, dtype = object)

где n - размер вашего массива

, хотя он работает, это может быть не лучшая идея, так как вам нужно импортировать библиотеку для этой цели. Надеюсь, это поможет!

0
ответ дан Mishaa1 21 August 2018 в 18:40
поделиться

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

Однако вы можете сделать что-то вроде l = [None] * 1000.

В качестве альтернативы вы можете использовать генератор.

3
ответ дан Russell Dias 21 August 2018 в 18:40
поделиться
  • 1
    Хорошо, я не очень хорошо разбираюсь в управлении памятью python, я передумаю. Спасибо ~ – wtm 16 May 2012 в 12:09

Обратите внимание, что когда вы использовали массивы на C ++, у вас могли быть несколько разные потребности, которые в Python решаются по-разному:

  1. Возможно, вам понадобился только набор элементов; Списки Python имеют дело с этим обычным способом.
  2. Возможно, вам понадобился правильный массив однородных элементов. Списки Python не являются хорошим способом хранения массивов .

Python решает необходимость в массивах с помощью NumPy , который, среди других опрятных вещи, имеет способ создать массив известного размера:

from numpy import *

l = zeros(10)
3
ответ дан ulidtko 21 August 2018 в 18:40
поделиться
  • 1
    Использование from numpy import * скроет встроенные функции python all, abs, min, max, sum, any и round с эквивалентами numpy, что может не всегда быть тем, что вы хотите. – Lauritz V. Thaulow 16 May 2012 в 12:29
  • 2
    Да, будьте осторожны, что модуль numpy содержит довольно много имен (которые, тем не менее, удобны для использования в пространстве имен модулей при написании кода массива). Если возможные столкновения имен вызывают проблемы, используйте квалифицированный импорт. – ulidtko 16 May 2012 в 13:14
Другие вопросы по тегам:

Похожие вопросы: