Есть более чем вероятное предположение, что все объекты из списка относятся к одному человеку.
Имеется ли более-менее вменяемый алгоритм, позволяющий это проверить и "схлопнуть" список в один максимально заполненный объект (как последний в списке), который и вернуть?
По принципу "пустое поле == заполненному или имеющему такое же значение"
Спасибо
PS. Количество элементов в списке может быть произвольным
Здравствуйте, mDmitriy, Вы писали:
D>Имеется ли более-менее вменяемый алгоритм, позволяющий это проверить и "схлопнуть" список в один максимально заполненный объект (как последний в списке), который и вернуть? D>По принципу "пустое поле == заполненному или имеющему такое же значение"
В такой постановне не сложно, O(N). Пробегашь по списку, когда встречаешь значение поля, записываешь его в результат (в заполненный объект).
Если встретил значение, отличное от того, которое уже лежит в результате, то возвращаешь ошибку.
D>Есть более чем вероятное предположение, что все объекты из списка относятся к одному человеку. D>Имеется ли более-менее вменяемый алгоритм, позволяющий это проверить и "схлопнуть" список в один максимально заполненный объект (как последний в списке), который и вернуть? D>По принципу "пустое поле == заполненному или имеющему такое же значение"
D>Спасибо
D>PS. Количество элементов в списке может быть произвольным
Просто завести 3 переменные SurName,FirstName и Patronymic с начальными значениями "" и в цикле сравнивать с полями. Если переменная пуста, присваивать ей значение поля. Если не пуста — сравнивать ее с полем, при неравенстве — предположение неверно, при равенстве — ничего не делать.
После цикла создать новую Person с этими значениями, а список выкинуть.
По-момему код выбирает один элемент из списка, а надо было объединить несколько элементов в один
Проще написать "объединялку" значений (сорри за питон в .NET-разделе)
def combineValues(values: List[str]) -> str:
validValues = (v for v in values if v != "")
return next(validValues, "")
def combinePersons(persons: List[Person]) -> Person:
return Person(
SurName = combineValues(p.SurName for p in persons),
FirstName = combineValues(p.FirstName for p in persons),
Patronymic = combineValues(p.Patronymic for p in persons),
)
Полный работающий код
from typing import List
from dataclasses import dataclass
@dataclass
class Person:
SurName: str
FirstName: str
Patronymic: str
def combineValues(values: List[str]) -> str:
validValues = (v for v in values if v != "")
return next(validValues, "")
def combinePersons(persons: List[Person]) -> Person:
return Person(
SurName = combineValues(p.SurName for p in persons),
FirstName = combineValues(p.FirstName for p in persons),
Patronymic = combineValues(p.Patronymic for p in persons),
)
print(
combinePersons([
Person("", "", "pat"),
Person("sur", "", "pat"),
Person("", "fir", "pat"),
])
)
Б>По-момему код выбирает один элемент из списка, а надо было объединить несколько элементов в один
Код sergii.p группирует объекты по признаку озвученному ТС ("пустое поле == заполненному или имеющему такое же значение") и выбирает самый заполненный объект из группы.
И он расчитан на нескольких реальных персон в списке, т.е. результат это список, в отличие от Вашего алгоритма.
Но работать будет не вполне корректно, хотя бы на том примере что я уже приводил:
Надо придумать более хитрый алгоритм: например придать разный вес полям при группировке.
Б>Проще написать "объединялку" значений (сорри за питон в .NET-разделе)
Помоему Ваш код рассчитан на то, что в списке только одна реальная персона, и надо просто скомбинировать значения из разных объектов Person вместе.
Тогда как ТС, ставит перед алгоритмом две задачи:
предположение, что все объекты из списка относятся к одному человеку.
<...>
позволяющий это проверить
схлопнуть" список в один максимально заполненный объект (как последний в списке),