#python #arrays
#python #массивы
Вопрос:
Эй, ребята, я работаю с набором данных, который содержит 14 столбцов (идентификатор отдела, идентификатор сотрудника и месяцы года), показывающих, сколько часов каждый сотрудник работал за каждый месяц.
Функция, с которой я работаю, должна распечатать строку для сотрудников, которые записывают нулевое значение за определенный месяц, когда его / ее отдел (в целом) записал ненулевое значение (т. Е. Джон в маркетинге записал нулевые часы за май, когда общее количество отделов составило 500 часов, поэтому мы печатаем Джонастрока).
У меня есть две вспомогательные функции: cost_center_sum(A)
которая принимает 2D-массив данных (организованный в виде списка списков) и находит совокупные часы для каждого отдела в виде списка списков. Вторая вспомогательная функция, compcols(row, A)
, сопоставляет идентификатор отдела «row» с соответствующей строкой в наборе данных A и проверяет, соответствует ли нулевое значение в «строке» для определенного месяца нулю за тот же месяц в строке, соответствующей в A.
Я попытался скомпилировать эти две функции в функцию, findgaps(A)
, которая печатает информацию о сотруднике для сотрудника, который записывает ноль в течение месяца, когда отдел записал ненулевое значение.
Ниже приведен код для функций, которые я описал выше:
def compcols(row, A):
for i in range(len(A)):
if len(A[i]) < len(row):
print row, (" - beware : line %d len(A[i]) %d < len(row) %d"
%(i, len(A[i]), len(row)))
else:
if row[0]==A[i][0]:
for j in range(len(row)):
if row[j]==0 and A[i][j]!=0:
print row
break
NUMBER_OF_MONTHS = 12
def cost_center_sum(A):
dep = dict()
for row in A:
if row[0] not in dep:
dep[row[0]] = [0.0 for x in xrange(NUMBER_OF_MONTHS)]
for i in xrange(NUMBER_OF_MONTHS):
dep[row[0]][i] = row[i 2]
ret = list()
for department in sorted(dep.iterkeys()):
x = [department]
x.extend(dep[department])
ret.append(x)
return ret
def findgaps(A):
X=cost_center_sum(A)
for i in range(len(A)):
for j in range(len(A[0])):
if A[i][j] < 0.00001:
return compcols(A[i],X)
Я протестировал другие функции, и они, похоже, выполняют свою работу довольно хорошо (есть небольшая ошибка, при compcol
которой одна и та же строка выводится несколько раз), но когда я использую findgaps
функцию, она выдает совершенно неверный вывод только одной строки сотрудника, напечатанной 80 раз:
[10017.0, 93454.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.6, 0.0] - beware : line 76 len(A[i]) 13 < len(row) 14
[10017.0, 93454.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.6, 0.0] - beware : line 77 len(A[i]) 13 < len(row) 14
[10017.0, 93454.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.6, 0.0] - beware : line 78 len(A[i]) 13 < len(row) 14
[10017.0, 93454.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.6, 0.0] - beware : line 79 len(A[i]) 13 < len(row) 14
[10017.0, 93454.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.6, 0.0] - beware : line 80 len(A[i]) 13 < len(row) 14
Ответ №1:
findgaps
выполняется только return
один раз; после первого вызова compcols
функция завершается:
def findgaps(A):
X=cost_center_sum(A)
for i in range(len(A)):
for j in range(len(A[0])):
if A[i][j] < 0.00001:
return compcols(A[i],X) # only ever returns once
Вместо этого это должно быть что-то вроде:
def findgaps(A):
X = cost_center_sum(A)
for row in A:
if any(month < 0.00001 for month in row[2:]):
yield compcols(row, X)
Это «генератор», который будет возвращать несколько значений. Обратите внимание, что вам не нужны индексы i
и j
— они только усложняют код, и вы можете увидеть, насколько он понятнее, когда вы перебираете сами объекты.
Далее compcols
сообщается о «предупреждениях» независимо от того, соответствует ли первый элемент или нет. Я думаю, что вместо этого должно быть:
def compcols(row, X):
for dept_row in X:
if row[0] == dept_row[0]:
for emp_month, dep_month in zip(row[2:], dept_row[2:])
if emp_month == 0 and dep_month != 0:
return row
else:
print "No match for department {0}.".format(row[0])