7

Is is possible to create a default initializer to python dataclasses initializing a 2D array, i.e. resulting in the same as

from dataclasses import dataclass, field
from typing import List
MAX = 5
@dataclass
class AlgoData:
    list2D: List[List[int]]  # = ???
    list1D: List[int] = field(default_factory=list)

b = [[] for m in range(MAX)]
a = AlgoData(b)

but without the b argument. Result:

AlgoData(list2D=[[], [], [], [], []], list1D=[])
mrtnlrsn
  • 1,105
  • 11
  • 19

2 Answers2

10

You can use a lambda function instead as a default_factory for field:

from dataclasses import dataclass, field
from typing import List
MAX = 5
@dataclass
class AlgoData:
    list2D: List[List[int]] = field(default_factory=lambda: [[] for m in range(MAX)])
    list1D: List[int] = field(default_factory=list)

a = AlgoData()

a becomes:

AlgoData(list2D=[[], [], [], [], []], list1D=[])
blhsing
  • 91,368
  • 6
  • 71
  • 106
2

An alternative may be to assign the attributes after initialization (via __post_init__).

Given

from typing import List

from dataclasses import dataclass, field


MAX = 5

Code

@dataclass
class AlgoData:
    """Algorithm data."""
    list1D: List[int] = None
    list2D: List[List[int]] = field(default_factory=list)

    def __post_init__(self):

        self.list2D = [[] for _ in range(MAX)]

Demo

a = AlgoData()
a
# AlgoData(list2D=[[], [], [], [], []], list1D=[])
pylang
  • 40,867
  • 14
  • 129
  • 121