在Python中初始化一个固定大小的数组[重复]
Posted
技术标签:
【中文标题】在Python中初始化一个固定大小的数组[重复]【英文标题】:Initialising an array of fixed size in Python [duplicate] 【发布时间】:2011-09-02 19:35:22 【问题描述】:我想知道如何初始化一个尚未填充值的数组(或列表),使其具有定义的大小。
例如在 C 中:
int x[5]; /* declared without adding elements*/
如何在 Python 中做到这一点?
【问题讨论】:
所有这些:***.com/search?q=%5Bpython%5D+array+of+fixed+size. Python, forcing a list to a fixed size 的可能重复项或者这个:***.com/questions/4056768/… 更有趣的问题是您为什么要这样做。我看到需要这样做的大多数情况都是由于错误的决定。 你几乎不需要这个。在 99% 的情况下,您可以一举生成值,例如使用列表理解,或者您只需在while
循环或类似的东西中从 []
和 .append()
或 .expand()
开始(列表过度分配,因此调整大小摊销 O(1))。
你应该解释你需要这个的动机。表现?安全?与 C/C++/NumPy/...的接口?
【参考方案1】:
你可以使用:
>>> lst = [None] * 5
>>> lst
[None, None, None, None, None]
【讨论】:
问题指定“.. 尚未填充值”。 Python 文档指出“None
通常用于表示缺少值”。我的示例以最短的代码量生成了这样一个定义大小的列表。在提出问题时,它是最接近惯用 Python 的东西。
这符合问题的要求,因为您有一个定义大小的数组,并且您可以索引五个元素之一而无需获得IndexError
。这是最接近 C 表达式的东西。
@user2233706 如果数组填充零,它会更接近 C。
你可以做 lst = [0] * 5 是你想要的 >>> [0]*5
[0, 0, 0, 0, 0]
需要注意的一点:列表中的所有元素最初都将具有相同的 id(或内存地址)。当您稍后在代码中更改任何元素时,这只会影响指定的值, - 但是 - 如果您以这种方式创建自定义对象列表(使用 int 乘数),然后您更改自定义对象的任何属性,这将更改列表中的所有对象。【参考方案2】:
为什么这些问题没有得到显而易见的答案?
a = numpy.empty(n, dtype=object)
这将创建一个可以存储对象的长度为 n 的数组。它不能调整大小或附加到。特别是,它不会通过填充长度来浪费空间。这是 Java 的 Python 等价物
Object[] a = new Object[n];
如果您真的对性能和空间感兴趣并且知道您的数组将只存储某些数字类型,那么您可以将 dtype 参数更改为其他值,例如 int。然后 numpy 会将这些元素直接打包到数组中,而不是让数组引用 int 对象。
【讨论】:
如果它是那么明显的话,其他人会提供这个..再一次,导入一个库只是为了获得这个功能可能不是最好的选择。 除了这是这里唯一真正正确的答案。 OP 没有指定禁止加载模块。他也没有要一份清单。这个问题非常具体,这个答案是正确的。 +1 添加大型模块如 numpy 是不必要的开销 你能解释一下为什么选择dtype=object
而不是其他一些dtype
吗?
澄清一下,这个实现是否具有典型的数组 O(1) 访问时间而不是链表的 O(n) 访问时间?【参考方案3】:
这样做:
>>> d = [ [ None for y in range( 2 ) ] for x in range( 2 ) ]
>>> d
[[None, None], [None, None]]
>>> d[0][0] = 1
>>> d
[[1, None], [None, None]]
其他解决方案会导致此类问题:
>>> d = [ [ None ] * 2 ] * 2
>>> d
[[None, None], [None, None]]
>>> d[0][0] = 1
>>> d
[[1, None], [1, None]]
【讨论】:
他问的是数组而不是列表 好答案。你提到的问题让我在编程比赛中搞砸了。您知道造成这种情况的确切机制吗? Python 按值复制“普通旧数据类型”,其余按引用复制,当其中一种发生时并不总是很清楚。 如果有人想知道,行为是(TLDR 第一个乘数创建n
长度数组,第二个乘数通过引用复制第一个数组来创建m
长度的数组列表)解释here docs.python.org/2/faq/…【参考方案4】:
最好的办法是使用numpy 库。
from numpy import ndarray
a = ndarray((5,),int)
【讨论】:
最好吗? 仅仅为了使用数组就必须导入库并不是最好的选择。还有其他方法。【参考方案5】:>>> import numpy
>>> x = numpy.zeros((3,4))
>>> x
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
>>> y = numpy.zeros(5)
>>> y
array([ 0., 0., 0., 0., 0.])
x 是二维数组,y 是一维数组。它们都用零初始化。
【讨论】:
你应该提供一种解释......【参考方案6】:一个简单的解决方案是x = [None]*length
,但请注意它将所有列表元素初始化为None
。如果尺寸真的是固定的,您也可以使用x=[None,None,None,None,None]
。但严格来说,无论哪种方式,您都不会得到未定义的元素,因为这种瘟疫在 Python 中不存在。
【讨论】:
对于大多数 C 使用数组的 cass,普通(非固定)列表是惯用的 python 等价物。这是问题的答案,因为它可能对 OP(从 C 转换到 Python)最有帮助。【参考方案7】:>>> n = 5 #length of list
>>> list = [None] * n #populate list, length n with n entries "None"
>>> print(list)
[None, None, None, None, None]
>>> list.append(1) #append 1 to right side of list
>>> list = list[-n:] #redefine list as the last n elements of list
>>> print(list)
[None, None, None, None, 1]
>>> list.append(1) #append 1 to right side of list
>>> list = list[-n:] #redefine list as the last n elements of list
>>> print(list)
[None, None, None, 1, 1]
>>> list.append(1) #append 1 to right side of list
>>> list = list[-n:] #redefine list as the last n elements of list
>>> print(list)
[None, None, 1, 1, 1]
或者列表中没有任何内容:
>>> n = 5 #length of list
>>> list = [] # create list
>>> print(list)
[]
>>> list.append(1) #append 1 to right side of list
>>> list = list[-n:] #redefine list as the last n elements of list
>>> print(list)
[1]
第 4 次 append 迭代:
>>> list.append(1) #append 1 to right side of list
>>> list = list[-n:] #redefine list as the last n elements of list
>>> print(list)
[1,1,1,1]
5 和所有后续:
>>> list.append(1) #append 1 to right side of list
>>> list = list[-n:] #redefine list as the last n elements of list
>>> print(list)
[1,1,1,1,1]
【讨论】:
【参考方案8】:你可以尝试使用描述符,来限制大小
class fixedSizeArray(object):
def __init__(self, arraySize=5):
self.arraySize = arraySize
self.array = [None] * self.arraySize
def __repr__(self):
return str(self.array)
def __get__(self, instance, owner):
return self.array
def append(self, index=None, value=None):
print "Append Operation cannot be performed on fixed size array"
return
def insert(self, index=None, value=None):
if not index and index - 1 not in xrange(self.arraySize):
print 'invalid Index or Array Size Exceeded'
return
try:
self.array[index] = value
except:
print 'This is Fixed Size Array: Please Use the available Indices'
arr = fixedSizeArray(5)
print arr
arr.append(100)
print arr
arr.insert(1, 200)
print arr
arr.insert(5, 300)
print arr
输出:
[None, None, None, None, None]
Append Operation cannot be performed on fixed size array
[None, None, None, None, None]
[None, 200, None, None, None]
This is Fixed Size Array: Please Use the available Indices
[None, 200, None, None, None]
【讨论】:
您的def __get__(self, instance, owner):
在这种情况下有何意义?相反,您应该定义__(set|get|del)item__()
,后者将它/它们设置为None
。【参考方案9】:
我觉得很容易做的一件事是我设置了一个数组 我喜欢的大小的空字符串,例如
代码:
import numpy as np
x= np.zeros(5,str)
print x
输出:
['' '' '' '' '']
希望这有帮助:)
【讨论】:
【参考方案10】:我想通过发布一个示例程序及其输出来帮助您
程序:
t = input("")
x = [None]*t
y = [[None]*t]*t
for i in range(1, t+1):
x[i-1] = i;
for j in range(1, t+1):
y[i-1][j-1] = j;
print x
print y
输出:-
2
[1, 2]
[[1, 2], [1, 2]]
我希望这可以清除您关于他们的声明的一些非常基本的概念。
要使用其他一些特定值初始化它们,例如使用 0
.. 初始化它们,您可以将它们声明为:
x = [0]*10
希望对您有所帮助..!! ;)
【讨论】:
您的代码没有按照问题的要求定义修复大小数组/列表。您只需将一些值放入列表中,它仍然可以是任意长度 为什么它是 -1 而 +12 的答案表明这样做的方式相同? @lejlot 因为 +12 的答案也是错误的,同样不回答原始问题 我不会说他们是错的,python 根本没有对内存管理的如此低级别的访问权限,而从实际的角度来看,提供的答案确实接近预期的行为 此解决方案不会达到您的预期。[[None] * t] * t
将创建相同“行”的t
副本列表。请参阅 Python 常见问题解答中的 this question。【参考方案11】:
如果您使用字节,您可以使用内置的bytearray
。如果您正在使用其他整数类型,请查看内置的 array
。
具体了解list
不是array
。
例如,如果您尝试创建一个缓冲区以将文件内容读入,您可以使用 bytearray,如下所示(有更好的方法,但示例有效):
with open(FILENAME, 'rb') as f:
data = bytearray(os.path.getsize(FILENAME))
f.readinto(data)
在这个 sn-p 中,bytearray
内存是预先分配的,固定长度为FILENAME
s 大小(以字节为单位)。这种预分配允许使用缓冲区协议更有效地将文件读入可变缓冲区,而无需数组副本。还有更好的方法可以做到这一点,但我相信这为您的问题提供了一个答案。
【讨论】:
以上是关于在Python中初始化一个固定大小的数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章