Mam dane 2D, do których chcę zastosować wiele funkcji. Rzeczywisty kod używa pliku xlrd
i .xlsx
, ale dostarczę następującą płytę kotła, dzięki czemu dane wyjściowe będą łatwe do odtworzenia.Zastosuj wiele funkcji na mapie
class Data:
def __init__(self, value):
self.value = value
class Sheet:
def __init__(self, data):
self.data = [[Data(value) for value in row.split(',')] for row in data.split('\n')]
self.ncols = max(len(row) for row in self.data)
def col(self, index):
return [row[index] for row in self.data]
Tworzenie arkusza:
fake_data = '''a, b, c,
1, 2, 3, 4
e, f, g,
5, 6, i,
, 6, ,
, , , '''
sheet = Sheet(fake_data)
W tym obiekcie, data
zawiera 2D tablicę ciągów (za formatu wejściowego) i chcę, aby wykonywać operacje na kolumnach tego obiektu. Nic do tej pory nie jest pod moją kontrolą.
Chcę zrobić trzy rzeczy do tej struktury: transponuj wiersze do kolumn, wyodrębnijz każdego obiektu Data
i spróbuj przekonwertować wartość na float
. Jeśli wartość nie jest równa float
, należy ją przekonwertować na str
z usuniętą białą przestrzenią.
from operators import attrgetter
# helper function
def parse_value(value):
try:
return float(value)
except ValueError:
return str(value).strip()
# transpose
raw_cols = map(sheet.col, range(sheet.ncols))
# extract values
value_cols = (map(attrgetter('value'), col) for col in raw_cols)
# convert values
typed_cols = (map(parse_value, col) for col in value_cols)
# ['a', 1.0, 'e', 5.0, '', '']
# ['b', 2.0, 'f', 6.0, 6.0, '']
# ['c', 3.0, 'g', 'i', '', '']
# ['', 4.0, '', '', '', '']
Można zauważyć, że map
jest stosowana do każdej kolumny dwukrotnie. W innych okolicznościach chcę zastosować funkcję do każdej kolumny więcej niż dwa razy.
Czy istnieje lepszy sposób odwzorowania wielu funkcji na wpisy w iteracji? Co więcej, czy jest tam, aby uniknąć zrozumienia generatora i bezpośrednio zastosować mapowanie do każdej wewnętrznej-iterowalnej? Czy istnieje lepszy i rozszerzalny sposób podejścia do tego wszystkiego?
Należy zauważyć, że to pytanie nie jest specyficzne dla xlrd
, jest to tylko aktualny przypadek użycia.
przypomnienia: 'mapy (m, mapy (g, nadmiar)) 'ma taką samą moc, jak' mapie (komponować (F, G), xs) '; pierwszy będzie dwukrotnie powtarzał kolekcję, ale drugi będzie tylko jeden raz. – naomik
@naomik Dobrze, chciałbym tylko, żeby było wbudowane 'compose'. –
Jared, z łatwością możesz zrobić własne. "compose" to nic innego jak "lambda f, g: lamda x: f (g (x))". Lub po prostu użyj 'map (lambda x: f (g (x)), xs)' – naomik