Maak een 3D-array met Python

Ik zou graag een 3D-array in Python (2.7) willen maken om als volgt te gebruiken:

distance[i][j][k]

En de grootte van de array moet de grootte zijn van een variabele die ik heb. (nnn)

Ik heb geprobeerd het volgende te gebruiken:

distance = [[[]*n]*n]

maar dat leek niet te werken.

Ik kan alleen de standaardbibliotheken gebruiken en de methode van vermenigvuldigen (dwz [[0]*n]*n) werkt niet omdat ze aan dezelfde aanwijzer zijn gekoppeld en ik ze allemaal nodig heb van de waarden die individueel moeten zijn


Antwoord 1, autoriteit 100%

U moet een lijstbegripgebruiken:

>>> import pprint
>>> n = 3
>>> distance = [[[0 for k in xrange(n)] for j in xrange(n)] for i in xrange(n)]
>>> pprint.pprint(distance)
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
 [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
 [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
>>> distance[0][1]
[0, 0, 0]
>>> distance[0][1][2]
0

Je had een datastructuur kunnen maken met een statement dat eruitzag als degene die je hebt geprobeerd, maar het zou bijwerkingen hebben gehad omdat de binnenste lijsten per referentie zijn:

>>> distance=[[[0]*n]*n]*n
>>> pprint.pprint(distance)
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
 [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
 [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
>>> distance[0][0][0] = 1
>>> pprint.pprint(distance)
[[[1, 0, 0], [1, 0, 0], [1, 0, 0]],
 [[1, 0, 0], [1, 0, 0], [1, 0, 0]],
 [[1, 0, 0], [1, 0, 0], [1, 0, 0]]]

Antwoord 2, autoriteit 53%

numpy.arrays zijn speciaal voor dit geval ontworpen:

numpy.zeros((i,j,k))

geeft u een reeks dimensies ijk, gevuld met nullen.

afhankelijk van waar je het voor nodig hebt, is numpywellicht de juiste bibliotheek voor je behoeften.


Antwoord 3, autoriteit 9%

De juiste manier zou zijn

[[[0 for _ in range(n)] for _ in range(n)] for _ in range(n)]

(Wat je probeert te doen moet worden geschreven als (voor NxNxN)

[[[0]*n]*n]*n

maar dat is niet correct, zie @Adaman commentaar waarom).


Antwoord 4, autoriteit 5%

d3 = [[[0 for col in range(4)]for row in range(4)] for x in range(6)]
d3[1][2][1]  = 144
d3[4][3][0]  = 3.12
for x in range(len(d3)):
    print d3[x]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 144, 0, 0], [0, 0, 0, 0]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3.12, 0, 0, 0]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Antwoord 5, autoriteit 5%

"""
Create 3D array for given dimensions - (x, y, z)
@author: Naimish Agarwal
"""
def three_d_array(value, *dim):
    """
    Create 3D-array
    :param dim: a tuple of dimensions - (x, y, z)
    :param value: value with which 3D-array is to be filled
    :return: 3D-array
    """
    return [[[value for _ in xrange(dim[2])] for _ in xrange(dim[1])] for _ in xrange(dim[0])]
if __name__ == "__main__":
    array = three_d_array(False, *(2, 3, 1))
    x = len(array)
    y = len(array[0])
    z = len(array[0][0])
    print x, y, z
    array[0][0][0] = True
    array[1][1][0] = True
    print array

Gebruik liever numpy.ndarrayvoor multidimensionale arrays.


Antwoord 6, autoriteit 4%

Je kunt ook een geneste for-lus gebruiken, zoals hieronder weergegeven

n = 3
arr = []
for x in range(n):
    arr.append([])
    for y in range(n):
        arr[x].append([])
        for z in range(n):
            arr[x][y].append(0)
print(arr)

Antwoord 7

Er zijn veel manieren om uw probleem aan te pakken.

  1. Eerste als geaccepteerd antwoord door @robert. Hier is de gegeneraliseerde
    oplossing ervoor:
def multi_dimensional_list(value, *args):
  #args dimensions as many you like. EG: [*args = 4,3,2 => x=4, y=3, z=2]
  #value can only be of immutable type. So, don't pass a list here. Acceptable value = 0, -1, 'X', etc.
  if len(args) > 1:
    return [ multi_dimensional_list(value, *args[1:]) for col in range(args[0])]
  elif len(args) == 1: #base case of recursion
    return [ value for col in range(args[0])]
  else: #edge case when no values of dimensions is specified.
    return None

Bijvoorbeeld:

>>> multi_dimensional_list(-1, 3, 4)  #2D list
[[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]]
>>> multi_dimensional_list(-1, 4, 3, 2)  #3D list
[[[-1, -1], [-1, -1], [-1, -1]], [[-1, -1], [-1, -1], [-1, -1]], [[-1, -1], [-1, -1], [-1, -1]], [[-1, -1], [-1, -1], [-1, -1]]]
>>> multi_dimensional_list(-1, 2, 3, 2, 2 )  #4D list
[[[[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]]], [[[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]]]]

P.S. Als je validatie wilt doen voor correcte waarden voor args, d.w.z. alleen natuurlijke getallen, dan kun je een wrapper-functie schrijven voordat je deze functie aanroept.

  1. Ten tweede kan elke multidimensionale array worden geschreven als een array met één dimensie. Dit betekent dat u geen multidimensionale array nodig heeft. Hier zijn de functies voor indexconversie:
def convert_single_to_multi(value, max_dim):
  dim_count = len(max_dim)
  values = [0]*dim_count
  for i in range(dim_count-1, -1, -1): #reverse iteration
    values[i] = value%max_dim[i]
    value /= max_dim[i]
  return values
def convert_multi_to_single(values, max_dim):
  dim_count = len(max_dim)
  value = 0
  length_of_dimension = 1
  for i in range(dim_count-1, -1, -1): #reverse iteration
    value += values[i]*length_of_dimension
    length_of_dimension *= max_dim[i]
  return value

Aangezien deze functies inverse van elkaar zijn, is hier de uitvoer:

>>> convert_single_to_multi(convert_multi_to_single([1,4,6,7],[23,45,32,14]),[23,45,32,14])
[1, 4, 6, 7]
>>> convert_multi_to_single(convert_single_to_multi(21343,[23,45,32,14]),[23,45,32,14])
21343
  1. Als u zich zorgen maakt over prestatieproblemen, kunt u enkele bibliotheken gebruiken, zoals panda’s, numpy, enz.

Antwoord 8

n1=np.arange(90).reshape((3,3,-1))
print(n1)
print(n1.shape)

Antwoord 9

def n_arr(n, default=0, size=1):
    if n is 0:
        return default
    return [n_arr(n-1, default, size) for _ in range(size)]
arr = n_arr(3, 42, 3)
assert arr[2][2][2], 42

Antwoord 10

Als je erop staat dat alles als leeg initialiseert, heb je een extra set haakjes aan de binnenkant nodig ([[]] in plaats van [], aangezien dit “een lijst is met 1 lege lijst die moet worden gedupliceerd” in plaats van ” een lijst met niets om te dupliceren”):

distance=[[[[]]*n]*n]*n

Other episodes