Подтвердить что ты не робот

Как создать список исправлений в python?

В С++ я могу создать массив вроде...

int* a = new int[10];

в python, я просто знаю, что могу объявить список, чем добавлять некоторые элементы или как..

l = [1,2,3,4]
l = range(10)

Можно ли инициализировать список заданным размером, например, С++, и не выполнять никаких заданий?

4b9b3361

Ответ 1

(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

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


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

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

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

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

>>> l = [None] * 4
>>> l
[None, None, None, None]

Ответ 4

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

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

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

Ответ 5

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

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

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

from numpy import *

l = zeros(10)

Ответ 6

your_list = [None]*size_required

Ответ 7

fix_array = numpy.empty(n, dtype = object)

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

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

Ответ 8

Вы можете сделать это с помощью модуля массива. Модуль массива является частью стандартной библиотеки Python:

from array import array
from itertools import repeat

a = array("i", repeat(0, 10))
# or
a = array("i", [0]*10)

повтор функция повторяет значение 0 в 10 раз. Он более эффективен по памяти, чем [0] * 10, поскольку он не выделяет память, а повторяет, возвращая одно и то же число x количество раз.

Ответ 9

Это скорее предупреждение, чем ответ.
Увидев в других ответах my_list = [None] * 10, я my_list = [None] * 10 искушение и настроил массив, подобный этому speakers = [['','']] * 10 и очень пожалел об этом, поскольку результирующий list не вел себя как я и думал.
Я прибег к:

speakers = []
for i in range(10):
    speakers.append(['',''])

Как [['','']] * 10 появляется для создания list где последующие элементы являются копией первого элемента.
например:

>>> n=[['','']]*10
>>> n
[['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', '']]
>>> n[0][0] = "abc"
>>> n
[['abc', ''], ['abc', ''], ['abc', ''], ['abc', ''], ['abc', ''], ['abc', ''], ['abc', ''], ['abc', ''], ['abc', ''], ['abc', '']]
>>> n[0][1] = "True"
>>> n
[['abc', 'True'], ['abc', 'True'], ['abc', 'True'], ['abc', 'True'], ['abc', 'True'], ['abc', 'True'], ['abc', 'True'], ['abc', 'True'], ['abc', 'True'], ['abc', 'True']]

Принимая во внимание, что с опцией .append:

>>> n=[]
>>> for i in range(10):
...  n.append(['',''])
... 
>>> n
[['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', '']]
>>> n[0][0] = "abc"
>>> n
[['abc', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', '']]
>>> n[0][1] = "True"
>>> n
[['abc', 'True'], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', ''], ['', '']]

Я уверен, что принятый ответ ninjagecko пытается упомянуть это, к сожалению, я был слишком толст, чтобы понять.
Заворачивай, береги себя!