Làm thế nào để khai báo một mảng trong Python?


491

Làm cách nào để khai báo một mảng trong Python ?

Tôi không thể tìm thấy bất kỳ tham chiếu đến các mảng trong tài liệu.


121
Đối với một số lý do không thể hiểu được, Python gọi mảng "danh sách". Trường phái thiết kế ngôn ngữ "mọi người đều biết cái này được gọi là cái gì chúng ta sẽ gọi là cái gì đó khác". Đây là một lựa chọn tên đặc biệt xấu, vì nó trông giống như một danh sách được liên kết hơn là một mảng.
Glenn Maynard

42
@Glenn Maynard: có thể vì các mảng ngôn ngữ giống như C có độ dài cố định trong khi danh sách Python thì không. Nó giống như vectơ STL trong C ++ hoặc ArrayList trong Java.
MAK

128
Nó được gọi là một danh sách, bởi vì đó là một danh sách. [A (), 1, 'Foo', u'öäöäö ', 67L, 5.6]. Một danh sách. Một mảng là "sự sắp xếp các mục tại các địa chỉ cách đều nhau trong bộ nhớ máy tính" (wikipedia).
Lennart Regebro

35
Không có gì về thuật ngữ "mảng" được hiểu toàn cầu cho thấy độ dài cố định hoặc bất cứ điều gì về nội dung; đó chỉ là những hạn chế của việc triển khai mảng cụ thể của C. Các danh sách Python có khoảng cách đều nhau (con trỏ tới các đối tượng, bên trong) hoặc nếu __getitem__không sẽ là O (1).
Glenn Maynard

24
@Glenn, từ en.wikipedia.org/wiki/Array_data_itectture: "các phần tử của cấu trúc dữ liệu mảng được yêu cầu phải có cùng kích thước" (đúng với mảng của Python, không đúng với danh sách Python) và "bộ các bộ chỉ mục hợp lệ và địa chỉ của các phần tử (và do đó công thức đánh địa chỉ phần tử) thường được cố định trong khi mảng đang được sử dụng "(không đúng trong Python cho danh sách hoặc mảng).
Alex Martelli

Câu trả lời:


358
variable = []

Bây giờ variableđề cập đến một danh sách trống * .

Tất nhiên đây là một bài tập, không phải là một tuyên bố. Không có cách nào để nói trong Python "biến này không bao giờ nên đề cập đến bất cứ điều gì ngoài danh sách", vì Python được gõ động.


* Kiểu Python dựng sẵn mặc định được gọi là danh sách , không phải là mảng. Nó là một thùng chứa có chiều dài tùy ý có thể chứa một bộ sưu tập các đối tượng không đồng nhất (loại của chúng không quan trọng và có thể được trộn tự do). Điều này không nên nhầm lẫn với arraymô-đun , cung cấp một loại gần với arrayloại C ; nội dung phải đồng nhất (tất cả cùng loại), nhưng độ dài vẫn động.


11
Có thể khởi tạo nội dung của mảng như trong JavaScript không? (ví dụ: như variable = ["Hi", "Hello"];?)
Anderson Green

6
@AndersonGreen Có.
sepp2k

3
Làm thế nào bạn sẽ khai báo một mảng nhiều chiều, sau đó (ví dụ, một mảng 2D?)
Anderson Green

7
@AndersonGreen Như tôi đã nói, không có thứ gọi là khai báo biến trong Python. Bạn sẽ tạo một danh sách đa chiều bằng cách lấy một danh sách trống và đặt các danh sách khác vào trong đó hoặc, nếu kích thước của danh sách được biết tại thời điểm viết, bạn có thể viết nó thành một nghĩa đen như thế này : my_2x2_list = [[a, b], [c, d]]. Tùy thuộc vào những gì bạn cần mảng nhiều chiều cho, bạn cũng có thể xem xét sử dụng numpy, trong đó xác định các kiểu mảng cho mảng đa chiều, đồng nhất, không có hộp có thể hiệu quả hơn nhiều khi áp dụng, vì vậy chúng thích hợp hơn cho tính toán số.
sepp2k

1
@ IfanIqbal Có, nếu nó chứa ít nhất một yếu tố, bạn có thể.
sepp2k

136

Đây là chủ đề phức tạp đáng ngạc nhiên trong Python.

Câu trả lời thực tế

Mảng được đại diện bởi lớp list(xem tài liệu tham khảo và không trộn chúng với máy phát điện ).

Kiểm tra các ví dụ sử dụng:

# empty array
arr = [] 

# init with values (can contain mixed types)
arr = [1, "eels"]

# get item by index (can be negative to access end of array)
arr = [1, 2, 3, 4, 5, 6]
arr[0]  # 1
arr[-1] # 6

# get length
length = len(arr)

# supports append and insert
arr.append(8)
arr.insert(6, 7)

Câu trả lời lý thuyết

Dưới mui xe Python listlà một trình bao bọc cho một mảng thực có chứa các tham chiếu đến các mục. Ngoài ra, mảng bên dưới được tạo ra với một số không gian thêm.

Hậu quả của việc này là:

  • truy cập ngẫu nhiên thực sự rẻ ( arr[6653]tương tự arr[0])
  • append hoạt động là 'miễn phí' trong khi một số không gian thêm
  • insert hoạt động tốn kém

Kiểm tra bảng phức tạp hoạt động tuyệt vời này .

Ngoài ra, vui lòng xem ảnh này, nơi tôi đã cố gắng thể hiện sự khác biệt quan trọng nhất giữa mảng, mảng tham chiếu và danh sách được liên kết: mảng, mảng ở khắp mọi nơi


5
Chỉ cần thêm vào, có một cách thực sự thú vị để cắt mảng trong python: [1, 2, 3, 4, 5, 6, 7, 8, 9][1:-2]kết quả sẽ là[2, 3, 4, 5, 6, 7]
Anton Purin

2
Tôi thấy một số phiếu giảm cho bài viết này theo thời gian. Sẽ thật tuyệt nếu ai đó có thể đăng một từ tại sao. Cảm ơn.
Anton Purin

2
Bạn da thật MVP. Cần biết thiết kế thực tế được chọn của 'danh sách' để đưa ra quyết định lập trình hợp lý. Về cơ bản, nó giống như một "vectơ" trong C ++. Cảm ơn!
Necro

Đây là một số câu trả lời dài thực sự với một số lời giải thích tuyệt vời!
Ahmed

Tôi có thể thêm ký hiệu thực tế để so sánh, ví dụ: a == b[:2]trả về True nếu 2 phần tử đầu tiên của b bằng với các giá trị của mảng a
Bruno L.

124

Bạn không thực sự khai báo mọi thứ, nhưng đây là cách bạn tạo một mảng trong Python:

from array import array
intarray = array('i')

Để biết thêm thông tin, hãy xem mô-đun mảng: http://docs.python.org/l Library / array.html

Bây giờ có thể bạn không muốn một mảng, nhưng một danh sách, nhưng những người khác đã trả lời điều đó rồi. :)


10
Đây là một loại buồn cười, nhưng không thực sự là một câu trả lời tốt cho một câu hỏi được gắn thẻ "người mới bắt đầu". Chỉ cần làm rõ: Trong Python bạn thường sử dụng một kiểu dữ liệu gọi là a list. Python có một kiểu dữ liệu cho mục đích đặc biệt gọi arraylà mảng C giống với mảng C hơn và ít được sử dụng.
steveha

63
Không, nhưng những người khác đã sử dụng một danh sách. Tôi nghĩ rằng nó sẽ là một câu trả lời tốt để chỉ ra rằng cũng có mảng.
Lennart Regebro

8
đạo cụ siêu điên cho câu trả lời này. Tôi đã lập trình bằng Python trong nhiều năm và chỉ gần đây mới nhận ra rằng có một đối tượng mảng Python thực sự khác với các đối tượng danh sách. Trong khi cấu trúc dữ liệu rất giống nhau, các mảng giới hạn loại đối tượng mà mảng có thể giữ. Câu trả lời tuyệt vời @LennartRegebro!
Josh Brown

4
Đây phải là câu trả lời đúng Danh sách và Mảng là hai điều khác nhau @LennartRegebro cảm ơn
Mina Gabriel

Có một lý do cụ thể mà bạn có thể muốn sử dụng mảng thay vì danh sách. Cụ thể, nếu bạn có một mảng gọi là myarray đầy đủ các số, bạn có thể thực hiện các phép toán đối với nó và các thao tác đó được áp dụng cho tất cả các mục bên trong nó. Vì vậy, nếu bạn thực hiện myarray / 3, mọi số bên trong được chia cho 3. Nếu bạn cố gắng làm điều tương tự với một danh sách, bạn sẽ gặp lỗi. Vì vậy, mảng là hiệu quả hơn cho các bộ dữ liệu lớn của số.
Matthew

66

Tôi nghĩ bạn (có nghĩa là) muốn có một danh sách với 30 ô đầu tiên đã được điền. Vì thế

   f = []

   for i in range(30):
       f.append(0)

Một ví dụ về nơi mà điều này có thể được sử dụng là trong chuỗi Fibonacci. Xem vấn đề 2 trong Project Euler


96
Đó là một cách khá baroque để khởi tạo một danh sách. Hãy thử f = [0] * 30thay thế.
John Machin

Không giống với a = phạm vi (10) từ @slehar anwer? Yêu trăn, đó là cú pháp và đó là Zen.
m3nda

@ erm3nda nope: $ python3 Python 3.4.2 [...] >>> a = phạm vi (10) >>> in (a) phạm vi (0, 10) >>>
arp

37

Đây là cách:

my_array = [1, 'rebecca', 'allard', 15]

4
Vì đây không phải là một mảng python mà là danh sách python, nên sẽ không khó hiểu hơn khi gọi nó là "my_list"?
Mattis Asp

4
Điều đó tạo ra một danh sách, không phải là một mảng. Chúng khác nhau và có các tính chất khác nhau trong trăn. Cụ thể, bạn có thể thực hiện các phép toán số đối với một mảng, nhưng không phải đối với một danh sách.
Matthew

21

Để tính toán, hãy sử dụng các mảng numpy như thế này:

import numpy as np

a = np.ones((3,2))        # a 2D array with 3 rows, 2 columns, filled with ones
b = np.array([1,2,3])     # a 1D array initialised using a list [1,2,3]
c = np.linspace(2,3,100)  # an array with 100 points beteen (and including) 2 and 3

print(a*1.5)  # all elements of a times 1.5
print(a.T+b)  # b added to the transpose of a

các mảng numpy này có thể được lưu và tải từ đĩa (thậm chí được nén) và các phép tính phức tạp với số lượng lớn các phần tử giống như C nhanh.

Được sử dụng nhiều trong môi trường khoa học. Xem ở đây để biết thêm.


17

Nhận xét của JohnMachin nên là câu trả lời thực sự. Tất cả các câu trả lời khác chỉ là cách giải quyết theo ý kiến ​​của tôi! Vì thế:

array=[0]*element_count

đồng ý. ngoại trừ cẩn thận để gọi ngay cả "mảng" biến, hoặc có được cơn thịnh nộ thuần túy. với điều này tôi cũng sẽ nói thêm rằng bạn có thể tạo ra "mảng đa chiều" tương tự:x=[[0] * 10] * 10
Peter S Magnusson

17

Một vài đóng góp cho thấy các mảng trong python được thể hiện bằng các danh sách. Điều này là không chính xác. Python có một triển khai độc lập array()trong mô-đun thư viện tiêu chuẩn array " array.array()" do đó không chính xác để nhầm lẫn giữa hai. Danh sách là danh sách trong python, vì vậy hãy cẩn thận với danh pháp được sử dụng.

list_01 = [4, 6.2, 7-2j, 'flo', 'cro']

list_01
Out[85]: [4, 6.2, (7-2j), 'flo', 'cro']

Có một sự khác biệt rất quan trọng giữa danh sách và array.array(). Trong khi cả hai đối tượng này được sắp xếp theo thứ tự, mảng.array () là một chuỗi đồng nhất có thứ tự trong khi danh sách là một chuỗi không đồng nhất.


16

Bạn không khai báo bất cứ điều gì trong Python. Bạn chỉ cần sử dụng nó. Tôi khuyên bạn nên bắt đầu với một cái gì đó như http://diveintopython.net .


2
Đôi khi bạn phải khai báo loại biến: nếu bạn không sử dụng nó trước đó, cấu trúc điều khiển, nó không tồn tại bên ngoài cấu trúc điều khiển và sau đó bạn sẽ xây dựng một biến mới. Giả định sau đó là biến là một int, nó sẽ xung đột nếu bạn sử dụng nó như một kiểu phức tạp hơn.
Rõ ràng hơn

@Clearer có, đôi khi sử dụng các hàm cần phải khai báo nó, và đôi khi để chơi một số toàn cục khi sử dụng các hàm và không muốn viết quá nhiều đối số trên các hàm.
m3nda

Nó không chỉ hoạt động; một câu lệnh if đơn giản có thể cho bạn cùng một vấn đề.
Rõ ràng hơn

1
Lập trình là tất cả về khai báo, bất kể bạn sử dụng ngôn ngữ nào. Khai báo kiểu là câu chuyện hoàn toàn khác
Bên ngoài_Box

Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi.
Adrian Tompkins


11

Để thêm vào câu trả lời của Lennart, một mảng có thể được tạo như thế này:

from array import array
float_array = array("f",values)

trong đó các giá trị có thể ở dạng một tuple, list hoặc np.array, nhưng không phải là mảng:

values = [1,2,3]
values = (1,2,3)
values = np.array([1,2,3],'f')
# 'i' will work here too, but if array is 'i' then values have to be int
wrong_values = array('f',[1,2,3])
# TypeError: 'array.array' object is not callable

và đầu ra vẫn sẽ giống nhau:

print(float_array)
print(float_array[1])
print(isinstance(float_array[1],float))

# array('f', [1.0, 2.0, 3.0])
# 2.0
# True

Hầu hết các phương thức cho danh sách cũng hoạt động với mảng, các phương thức phổ biến là pop (), extend () và append ().

Đánh giá từ các câu trả lời và nhận xét, có vẻ như cấu trúc dữ liệu mảng không phổ biến. Mặc dù vậy, tôi thích nó, giống như cách người ta có thể thích một tuple trong danh sách.

Cấu trúc mảng có các quy tắc chặt chẽ hơn so với danh sách hoặc np.array và điều này có thể giảm lỗi và giúp gỡ lỗi dễ dàng hơn, đặc biệt là khi làm việc với dữ liệu số.

Nỗ lực chèn / nối một float vào một mảng int sẽ ném TypeError:

values = [1,2,3]
int_array = array("i",values)
int_array.append(float(1))
# or int_array.extend([float(1)])

# TypeError: integer argument expected, got float

Do đó, việc giữ các giá trị có nghĩa là số nguyên (ví dụ: danh sách các chỉ mục) ở dạng mảng có thể ngăn "Chỉ số danh sách TypeError: phải là số nguyên, không nổi", vì các mảng có thể được lặp lại, tương tự như np.array và danh sách:

int_array = array('i',[1,2,3])
data = [11,22,33,44,55]
sample = []
for i in int_array:
    sample.append(data[i])

Khó chịu, việc thêm một int vào một mảng float sẽ khiến int trở thành một float, mà không đưa ra một ngoại lệ.

np.array cũng giữ nguyên kiểu dữ liệu cho các mục nhập của nó, nhưng thay vì đưa ra lỗi, nó sẽ thay đổi kiểu dữ liệu để phù hợp với các mục mới (thường là gấp đôi hoặc str):

import numpy as np
numpy_int_array = np.array([1,2,3],'i')
for i in numpy_int_array:
    print(type(i))
    # <class 'numpy.int32'>
numpy_int_array_2 = np.append(numpy_int_array,int(1))
# still <class 'numpy.int32'>
numpy_float_array = np.append(numpy_int_array,float(1))
# <class 'numpy.float64'> for all values
numpy_str_array = np.append(numpy_int_array,"1")
# <class 'numpy.str_'> for all values
data = [11,22,33,44,55]
sample = []
for i in numpy_int_array_2:
    sample.append(data[i])
    # no problem here, but TypeError for the other two

Điều này đúng trong quá trình chuyển nhượng là tốt. Nếu loại dữ liệu được chỉ định, np.array sẽ, bất cứ khi nào có thể, sẽ chuyển đổi các mục nhập thành loại dữ liệu đó:

int_numpy_array = np.array([1,2,float(3)],'i')
# 3 becomes an int
int_numpy_array_2 = np.array([1,2,3.9],'i')
# 3.9 gets truncated to 3 (same as int(3.9))
invalid_array = np.array([1,2,"string"],'i')
# ValueError: invalid literal for int() with base 10: 'string'
# Same error as int('string')
str_numpy_array = np.array([1,2,3],'str')
print(str_numpy_array)
print([type(i) for i in str_numpy_array])
# ['1' '2' '3']
# <class 'numpy.str_'>

hoặc, về bản chất:

data = [1.2,3.4,5.6]
list_1 = np.array(data,'i').tolist()
list_2 = [int(i) for i in data]
print(list_1 == list_2)
# True

trong khi mảng đơn giản sẽ cung cấp:

invalid_array = array([1,2,3.9],'i')
# TypeError: integer argument expected, got float

Bởi vì điều này, không nên sử dụng np.array cho các lệnh dành riêng cho loại. Cấu trúc mảng rất hữu ích ở đây. danh sách bảo tồn kiểu dữ liệu của các giá trị.

Và đối với một cái gì đó tôi thấy khá phiền phức: kiểu dữ liệu được chỉ định làm đối số đầu tiên trong mảng (), nhưng (thường) là thứ hai trong np.array (). : |

Mối quan hệ với C được đề cập ở đây: Danh sách Python so với Mảng - khi nào nên sử dụng?

Hãy vui vẻ khám phá!

Lưu ý: Bản chất được gõ và khá nghiêm ngặt của mảng dựa nhiều vào C hơn là Python và theo thiết kế Python không có nhiều ràng buộc về kiểu cụ thể trong các hàm của nó. Tính phổ biến của nó cũng tạo ra một phản hồi tích cực trong công việc cộng tác và thay thế nó chủ yếu liên quan đến một [int (x) bổ sung cho x trong tệp]. Do đó, hoàn toàn khả thi và hợp lý để bỏ qua sự tồn tại của mảng. Nó không nên cản trở hầu hết chúng ta bằng mọi cách. : D


8

Còn cái này thì sao...

>>> a = range(12)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> a[7]
6


5

Tiếp theo từ Lennart, cũng có numpy thực hiện các mảng đa chiều đồng nhất.


4

Tôi đã có một chuỗi các chuỗi và cần một mảng có cùng độ dài booleans được khởi tạo thành True. Đây là những gì tôi đã làm

strs = ["Hi","Bye"] 
bools = [ True for s in strs ]

Tôi ở đây vì tôi muốn khai báo C: int count[26]={0}; Có lẽ có một cách tốt hơn nhưng biến thể boolstừ trên đã hoạt động count=[0 for ii in range(26)]Sau đó, sau đó tôi đã thay đổi nó thành count=[0]*26có vẻ thích hợp hơn.
dùng1683793

2

Bạn có thể tạo danh sách và chuyển đổi chúng thành mảng hoặc bạn có thể tạo mảng bằng mô-đun numpy. Dưới đây là một vài ví dụ để minh họa tương tự. Numpy cũng làm cho nó dễ dàng hơn để làm việc với các mảng đa chiều.

import numpy as np
a = np.array([1, 2, 3, 4])

#For custom inputs
a = np.array([int(x) for x in input().split()])

Bạn cũng có thể định hình lại mảng này thành ma trận 2X2 bằng cách sử dụng chức năng định hình lại lấy đầu vào làm kích thước của ma trận.

mat = a.reshape(2, 2)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.