wake-up-neo.com

Python 2.7 Erstellen einer mehrdimensionalen Liste

In Python möchte ich auf intuitive Weise eine dreidimensionale Liste erstellen.

Ich möchte eine (n mal n) Liste. Für n = 4 sollte es also sein:

x = [[[],[],[],[]],[[],[],[],[]],[[],[],[],[]],[[],[],[],[]]]

Ich habe versucht mit:

y = [n*[n*[]]]    
y = [[[]]* n for i in range(n)]

Die beiden scheinen Kopien einer Referenz zu erstellen. Ich habe auch die naive Anwendung des List Builder mit wenig Erfolg versucht:

y = [[[]* n for i in range(n)]* n for i in range(n)]
y = [[[]* n for i in range(1)]* n for i in range(n)]

Ich habe auch versucht, das Array mithilfe von Schleifen iterativ aufzubauen, jedoch ohne Erfolg. Ich habe auch folgendes versucht:

y = []
for i in range(0,n):
    y.append([[]*n for i in range(n)])

Gibt es einen einfacheren oder intuitiveren Weg, dies zu tun?

14
poop

Ich glaube, dass Ihre Listenverständnisversionen sehr nahe an der Arbeit waren. Sie müssen keine Listenmultiplikation durchführen (was ohnehin nicht mit leeren Listen funktioniert). Hier ist eine funktionierende Version:

>>> y = [[[] for i in range(n)] for i in range(n)]
>>> print y
[[[], [], [], []], [[], [], [], []], [[], [], [], []], [[], [], [], []]]
16
Blckknght

der einfachste Weg sieht folgendermaßen aus:

def create_empty_array_of_shape(shape):
    if shape: return [create_empty_array_of_shape(shape[1:]) for i in xrange(shape[0])]

es ist Arbeit für mich

4
user2114402

ich habe das gefunden:

Matrix = [[0 for x in xrange(5)] for x in xrange(5)]

Sie können jetzt Elemente zur Liste hinzufügen:

Matrix[0][0] = 1
Matrix[4][0] = 5

print Matrix[0][0] # prints 1
print Matrix[4][0] # prints 5

von hier aus: So definieren Sie ein zweidimensionales Array in Python

2
user1505695

Wie wäre es damit:

class MultiDimList(object):
    def __init__(self, shape):
        self.shape = shape
        self.L = self._createMultiDimList(shape)
    def get(self, ind):
        if(len(ind) != len(self.shape)): raise IndexError()
        return self._get(self.L, ind)
    def set(self, ind, val):
        if(len(ind) != len(self.shape)): raise IndexError()
        return self._set(self.L, ind, val)
    def _get(self, L, ind):
        return self._get(L[ind[0]], ind[1:]) if len(ind) > 1 else L[ind[0]]
    def _set(self, L, ind, val):
        if(len(ind) > 1): 
            self._set(L[ind[0]], ind[1:], val) 
        else: 
            L[ind[0]] = val
    def _createMultiDimList(self, shape):
        return [self._createMultiDimList(shape[1:]) if len(shape) > 1 else None for _ in range(shape[0])]
    def __repr__(self):
        return repr(self.L)

Sie können es dann wie folgt verwenden

L = MultiDimList((3,4,5)) # creates a 3x4x5 list
L.set((0,0,0), 1)
L.get((0,0,0))
2
Konstantin

Hier erhalten Sie eine N-dimensionale "Matrix", die mit Kopien eines kopierbaren Objekts gefüllt ist.

Edit : Dies ist eine geringfügige Modifikation der ursprünglichen Antwort von pterodragon, die ich der weniger lesbaren Antwort von user2114402 sehr bevorzuge. Außerhalb eines Doc-Strings besteht der einzige Unterschied zur Lösung von Pterodragon darin, dass ich explizit eine Liste mit Dimensionsgrößen verwende, anstatt sie vom Benutzer als Argumente übergeben zu müssen.

import copy

    def instantiate_mdl(dim_maxes, base=0):
        """ Instantiate multi-dimensional list, that is a list of list of list ...

        Arguments:
            dim_maxes (list[int]): a list of dimension sizes, for example 
            [2, 4] represents a matrix (represented by lists) of 2 rows and 
            4 columns.     

            base (object): an optional argument indicating the object copies
            of which will reside at the lowest level in the datastructure.
        Returns:
            base (list[base]): a multi-dimensional list of lists structure,
            which is filled with clones of the base parameter.
        """
        for dim_max in reversed(dim_maxes):
            base = [copy.deepcopy(base) for i in range(dim_max)]
        return base

data = instantiate_mdl([3, 5])
data[0][0] = 99999
data[1][1] = 88888
data[2][4] = 77777

for r in data:
    print(r)

>>> # Output
>>> [99999, 0, 0, 0, 0]
>>> [0, 88888, 0, 0, 0]
>>> [0, 0, 0, 0, 77777]
1
darkhipo

Ich bin erstaunt, dass niemand versucht hat, einen generischen Weg zu finden, um dies zu tun .. Siehe meine Antwort hier: https://stackoverflow.com/a/33460217/5256940

import copy

def ndlist(init, *args):  # python 2 doesn't have kwarg after *args
    dp = init
    for x in reversed(args):
        dp = [copy.deepcopy(dp) for _ in xrange(x)] # Python 2 xrange
    return dp

l = ndlist(0, 1, 2, 3, 4) # 4 dimensional list initialized with 0's
l[0][1][2][3] = 1

Bearbeiten: Basierend auf der Antwort von user2114402: Standardwertparameter hinzugefügt

def ndlist(s, v):
    return [ndlist(s[1:], v) for i in xrange(s[0])] if s else v
1
pterodragon

In Python habe ich eine kleine Factory-Methode erstellt, um eine Liste mit variablen Dimensionen und variablen Größen für jede dieser Dimensionen zu erstellen:

def create_n_dimensional_matrix(self, n):
  dimensions = len(n)
  if (dimensions == 1): 
    return [0 for i in range(n[0])]

  if (dimensions == 2): 
    return [[0 for i in range(n[0])] for j in range(n[1])]

  if (dimensions == 3): 
    return [[[0 for i in range(n[0])] for j in range(n[1])] for k in range(n[2])]

  if (dimensions == 4): 
    return [[[[0 for i in range(n[0])] for j in range(n[1])] for k in range(n[2])] for l in range(n[3])]

führe es so aus:

print(str(k.create_n_dimensional_matrix([2,3])))
print(str(k.create_n_dimensional_matrix([3,2])))
print(str(k.create_n_dimensional_matrix([1,2,3])))
print(str(k.create_n_dimensional_matrix([3,2,1])))
print(str(k.create_n_dimensional_matrix([2,3,4,5])))
print(str(k.create_n_dimensional_matrix([5,4,3,2])))    

Welche drucke:

  1. Die zweidimensionalen Listen (2x3), (3x2)
  2. Die dreidimensionalen Listen (1x2x3), (3x2x1)
  3. Die vier dimensionalen Listen (2x3x4x5), (5x4x3x2)

    [[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], [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], [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, 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, 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, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]]
    
1
Eric Leschinski
import copy
dimensions = 2, 3, 4
z = 0
genList = lambda size,value: [copy.deepcopy(value) for i in range(size)]
for i in dimensions: z = genList(i, z)
1

Ein sehr einfacher und eleganter Weg ist:

a = [([0] * 5) for i in range(5)]
a
[[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]]
1
awangenh

Hier ist eine allgemeinere Methode, dies zu tun. 

def ndlist(shape, dtype=list):
    t = '%s for v%d in xrange(shape[%d])'
    cmd = [t % ('%s', i + 1, i) for i in xrange(len(shape))]
    cmd[-1] = cmd[-1] % str(dtype())
    for i in range(len(cmd) - 1)[::-1]:
        cmd[i] = cmd[i] % ('[' + cmd[i + 1]  + ']')
    return eval('[' + cmd[0] + ']')

list_4d = ndlist((2, 3, 4))
list_3d_int = ndlist((2, 3, 4), dtype=int)

print list_4d
print list_3d_int

Ergebnis:

[[[[], [], [], []], [[], [], [], []], [[], [], [], []]], [[[], [], [], []], [[], [], [], []], [[], [], [], []]]]
[[[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
Milad.H