Это дополнительные вопросы к этому:
Python DictReader - пропуск строк с пропущенными столбцами?
Оказывается, я был глуп, и использовал неправильное поле ID.
Я использую Python 3.x, кстати.
У меня есть команда сотрудников, проиндексированная строкой "directory_id". Каждое значение представляет собой вложенный диктант с атрибутами сотрудника (номер телефона, фамилия и т. Д.). Одним из этих значений является вторичный идентификатор, скажем «internal_id», а другое - их менеджер, назовите его «manager_internal_id». Поле «internal_id» не является обязательным, и не у каждого сотрудника есть.
{'6443410501': {'manager_internal_id': '989634', 'givenName': 'Mary', 'phoneNumber': '+65 3434 3434', 'sn': 'Jones', 'internal_id': '434214'}
'8117062158': {'manager_internal_id': '180682', 'givenName': 'John', 'phoneNumber': '+65 3434 3434', 'sn': 'Ashmore', 'internal_id': ''}
'9227629067': {'manager_internal_id': '347394', 'givenName': 'Wright', 'phoneNumber': '+65 3434 3434', 'sn': 'Earl', 'internal_id': '257839'}
'1724696976': {'manager_internal_id': '907239', 'givenName': 'Jane', 'phoneNumber': '+65 3434 3434', 'sn': 'Bronte', 'internal_id': '629067'}
}
(Я немного упростил поля, чтобы было легче читать, а также по соображениям конфиденциальности / соответствия).
Проблема здесь в том, что мы индексируем (ключим) каждого сотрудника по его directory_id, но когда мы ищем их менеджера, нам нужно найти менеджеров по их «внутреннему_иде».
Раньше, когда наш dict использовал internal_id в качестве ключа, employee.keys () представлял собой список internal_id, и я использовал проверку членства по этому вопросу. Теперь последняя часть моего оператора if не будет работать, так как internal_ids является частью значений dict, а не самого ключа.
def lookup_supervisor(manager_internal_id, employees):
if manager_internal_id is not None and manager_internal_id != "" and manager_internal_id in employees.keys():
return (employees[manager_internal_id]['mail'], employees[manager_internal_id]['givenName'], employees[manager_internal_id]['sn'])
else:
return ('Supervisor Not Found', 'Supervisor Not Found', 'Supervisor Not Found')
Итак, первый вопрос: как мне исправить оператор if, чтобы проверить, присутствует ли manager_internal_id в списке dict internal_ids?
Я пытался заменить employee.keys () на employee.values (), но это не сработало. Кроме того, я надеюсь на что-то более эффективное, не уверен, есть ли способ получить подмножество значений, в частности, все записи для сотрудников [directory_id] ['internal_id'].
Надеюсь, есть какой-то Pythonic способ сделать это, не используя огромную кучу вложенных циклов for / if.
Мой второй вопрос: как мне тогда правильно вернуть необходимые атрибуты сотрудника (почта, имя, фамилия и т. Д.). Мой цикл for выполняет итерацию по каждому сотруднику и вызывает lookup_supervisor. Я чувствую себя немного глупо / тупо здесь.
def tidy_data(employees):
for directory_id, data in employees.items():
# We really shouldnt' be passing employees back and forth like this - hmm, classes?
data['SupervisorEmail'], data['SupervisorFirstName'], data['SupervisorSurname'] = lookup_supervisor(data['manager_internal_id'], employees)
Должен ли я перепроектировать мою структуру данных? Или есть другой способ?
РЕДАКТИРОВАТЬ: Я немного подправил код, см. Ниже:
class Employees:
def import_gd_dump(self, input_file="test.csv"):
gd_extract = csv.DictReader(open(input_file), dialect='excel')
self.employees = {row['directory_id']:row for row in gd_extract}
def write_gd_formatted(self, output_file="gd_formatted.csv"):
gd_output_fieldnames = ('internal_id', 'mail', 'givenName', 'sn', 'dbcostcenter', 'directory_id', 'manager_internal_id', 'PHFull', 'PHFull_message', 'SupervisorEmail', 'SupervisorFirstName', 'SupervisorSurname')
try:
gd_formatted = csv.DictWriter(open(output_file, 'w', newline=''), fieldnames=gd_output_fieldnames, extrasaction='ignore', dialect='excel')
except IOError:
print('Unable to open file, IO error (Is it locked?)')
sys.exit(1)
headers = {n:n for n in gd_output_fieldnames}
gd_formatted.writerow(headers)
for internal_id, data in self.employees.items():
gd_formatted.writerow(data)
def tidy_data(self):
for directory_id, data in self.employees.items():
data['PHFull'], data['PHFull_message'] = self.clean_phone_number(data['telephoneNumber'])
data['SupervisorEmail'], data['SupervisorFirstName'], data['SupervisorSurname'] = self.lookup_supervisor(data['manager_internal_id'])
def clean_phone_number(self, original_telephone_number):
standard_format = re.compile(r'^\+(?P<intl_prefix>\d{2})\((?P<area_code>\d)\)(?P<local_first_half>\d{4})-(?P<local_second_half>\d{4})')
extra_zero = re.compile(r'^\+(?P<intl_prefix>\d{2})\(0(?P<area_code>\d)\)(?P<local_first_half>\d{4})-(?P<local_second_half>\d{4})')
missing_hyphen = re.compile(r'^\+(?P<intl_prefix>\d{2})\(0(?P<area_code>\d)\)(?P<local_first_half>\d{4})(?P<local_second_half>\d{4})')
if standard_format.search(original_telephone_number):
result = standard_format.search(original_telephone_number)
return '0' + result.group('area_code') + result.group('local_first_half') + result.group('local_second_half'), ''
elif extra_zero.search(original_telephone_number):
result = extra_zero.search(original_telephone_number)
return '0' + result.group('area_code') + result.group('local_first_half') + result.group('local_second_half'), 'Extra zero in area code - ask user to remediate. '
elif missing_hyphen.search(original_telephone_number):
result = missing_hyphen.search(original_telephone_number)
return '0' + result.group('area_code') + result.group('local_first_half') + result.group('local_second_half'), 'Missing hyphen in local component - ask user to remediate. '
else:
return '', "Number didn't match format. Original text is: " + original_telephone_number
def lookup_supervisor(self, manager_internal_id):
if manager_internal_id is not None and manager_internal_id != "":# and manager_internal_id in self.employees.values():
return (employees[manager_internal_id]['mail'], employees[manager_internal_id]['givenName'], employees[manager_internal_id]['sn'])
else:
return ('Supervisor Not Found', 'Supervisor Not Found', 'Supervisor Not Found')
if __name__ == '__main__':
our_employees = Employees()
our_employees.import_gd_dump('test.csv')
our_employees.tidy_data()
our_employees.write_gd_formatted()
Я думаю (1). Я ищу лучший способ структурировать / хранить сотрудников / сотрудников, и (2) у меня, в частности, проблемы с lookup_supervisor (). \
Должен ли я создавать класс Employee и вкладывать его в Employees?
И должен ли я даже делать то, что я делаю с tidy_data () и вызывать clean_phone_number () и lookup_supervisor () в цикле for для элементов dict? Urgh. смущенно .