Это относится к проекту по преобразованию двухсторонней программы ANOVA в SAS в Python.
Я в значительной степени начал пытаться изучать язык в четверг, поэтому я знаю, что у меня много возможностей для совершенствования. Если я что-то упустил очевидное, во что бы то ни стало, дайте мне знать. Я еще не запустил Sage и не работал, так что прямо сейчас, это все довольно ванильный Python 2.6.1. (Портативный)
Основной запрос: нужен хороший набор понятий для списков, которые могут извлекать данные в списках выборок в списках по фактору A, по фактору B в целом и по группам каждого уровня факторов A & B (AxB).
После некоторой работы данные отображаются в следующем виде (3 слоя вложенных списков):
ответ [A] [B] [N]
(имеется в виду [a1 [b1 [n1, ..., nN] ... [bB [n1, ... nN]]], ..., [aA [b1 [n1, ..., nN ] ... [bB [n1, ... nN]]]
Надеюсь, это понятно.)
Уровни фактора в моем примере: A = 3 (0-2), B = 8 (0-7), N = 8 (0-7)
byA= [[a[i] for i in range(b)] for a[b] in response]
(Может кто-нибудь объяснить , почему этот синтаксис работает? Я наткнулся на него, пытаясь понять, что синтаксический анализатор примет. хорошие ссылки на сайты или книги по этой теме приветствуются. Редактирование: Постоянство переменных между прогонами объяснило эту странность. Это не работает.)
byB=lstcrunch([[Bs[i] for i in range(len(Bs)) ]for Bs in response])
(Следует отметить, что zip(*response)
почти делает то, что я хочу. Вышеприведенная версия на самом деле не работает, насколько я помню. Я еще не прошел тщательный тест.)
byAxB= [item for sublist in response for item in sublist]
(Украдено из ответа Алекса Мартелли на этом сайте. Опять может кто-нибудь объяснить почему ? Синтаксис понимания списка не очень хорошо объяснен в текстах, которые я читал.)
ByO= [item for sublist in byAxB for item in sublist]
(Очевидно, я просто использовал здесь прежнее понимание, потому что оно сделало то, что мне нужно. Редактировать:)
Я бы хотел, чтобы эти типы данных заканчивались одним и тем же типом, по крайней мере, когда он проходит через рассматриваемый фактор, s.t. те же самые средние / sum / SS / и так далее функции могут применяться и использоваться.
Это можно легко заменить чем-нибудь более чистым:
def lstcrunch(Dlist):
"""Returns a list containing the entire
contents of whatever is imported,
reduced by one level.
If a rectangular array, it reduces a dimension by one.
lstcrunch(DataSet[a][b]) -> DataOutput[a]
[[1, 2], [[2, 3], [2, 4]]] -> [1, 2, [2, 3], [2, 4]]
"""
flat=[]
if islist(Dlist):#1D top level list
for i in Dlist:
if islist(i):
flat+= i
else:
flat.append(i)
return flat
else:
return [Dlist]
О, пока я нахожусь в теме, каков предпочтительный способ идентификации переменной в виде списка?
Я использовал:
def islist(a):
"Returns 'True' if input is a list and 'False' otherwise"
return type(a)==type([])
Запрос на расставание:
Есть ли способ явно заставить мелкую копию преобразовать в глубокую? копировать? Или, аналогично, при копировании в переменную, есть ли способ объявить, что присвоение также должно заменить указатель, а не просто значение? (s.t. назначение не будет распространяться на другие мелкие копии) Точно так же использование этого также может быть полезно время от времени, поэтому возможность контролировать, когда это происходит или не происходит, звучит очень хорошо.
(Я действительно перешагнул через себя, когда я подготовил свой стол для вставки, позвонив:
ответ = [[[0] * N] * B] * А
)
Редактировать :
Дальнейшее расследование привело к тому, что большая часть этого работала нормально. С тех пор я сделал класс и проверил его. это работает отлично. Я оставлю формы понимания списка нетронутыми для справки.
def byB(array_a_b_c):
y=range(len(array_a_b_c))
x=range(len(array_a_b_c[0]))
return [[array_a_b_c[i][j][k]
for k in range(len(array_a_b_c[0][0]))
for i in y]
for j in x]
def byA(array_a_b_c):
return [[repn for rowB in rowA for repn in rowB]
for rowA in array_a_b_c]
def byAxB(array_a_b_c):
return [rowB for rowA in array_a_b_c
for rowB in rowA]
def byO(array_a_b_c):
return [rep
for rowA in array_a_b_c
for rowB in rowA
for rep in rowB]
def gen3d(row, col, inner):
"""Produces a 3d nested array without any naughty shallow copies.
[row[col[inner]] named s.t. the outer can be split on, per lprn for easy display"""
return [[[k for k in range(inner)]
for i in range(col)]
for j in range(row)]
def lprn(X):
"""This prints a list by lines.
Not fancy, but works"""
if isiterable(X):
for line in X: print line
else:
print x
def isiterable(a):
return hasattr(a, "__iter__")
Спасибо всем, кто откликнулся. Я уже вижу заметное улучшение качества кода благодаря улучшениям в моем гнозисе. Конечно, мы все еще ценим дальнейшие мысли.