Как найти индексы одинаковых элементов в list?
Как найти индексы строк в которых Город и Улица одинаковые
class users:
def __init__(self, name, gorod, ulica):
self.name = name
self.gorod = gorod
self.ulica = ulica
list = []
list.append( users('Иван', 'Москва', 'Ленина') )
list.append( users('Андрей', 'Москва', 'Ленина') )
list.append( users('Андрей', 'Москва', 'Маяковского') )
list.append( users('Артём', 'Ростов', 'Горького') )
list.append( users('Анна', 'Астрахань', 'Петрова') )
list.append( users('Артём', 'Астрахань', 'Петрова') )
На выходе должно получиться
list.append( users('Иван', 'Москва', 'Ленина_1') )
list.append( users('Андрей', 'Москва', 'Ленина_2') )
list.append( users('Андрей', 'Москва', 'Маяковского') )
list.append( users('Артём', 'Ростов', 'Горького') )
list.append( users('Анна', 'Астрахань', 'Петрова_1') )
list.append( users('Артём', 'Астрахань', 'Петрова_2') )
Ответы (2 шт):
Автор решения: farkon00
→ Ссылка
for i in range(len(list)):
k = 2
is_added = False
for j in range(i, len(list)):
if i != j and list[i].gorod == list[j].gorod and list[i].ulica == list[j].ulica:
if not is_added:
list[i].ulica = list[i].ulica + '_1'
is_added = True
list[j].ulica = list[j].ulica + f'_{str(k)}'
k+=1
Результат(Это вывод через for и str, сам массив продолжает состоять из объектов, только изменённых) :
Name:Иван, Gorod:Москва, Ulica:Ленина_1
Name:Андрей, Gorod:Москва, Ulica:Ленина_2
Name:Андрей, Gorod:Москва, Ulica:Маяковского
Name:Артём, Gorod:Ростов, Ulica:Горького
Name:Анна, Gorod:Астрахань, Ulica:Петрова_1
Name:Артём, Gorod:Астрахань, Ulica:Петрова_2
Немного не оптимизировано, но работает. Если список не будет прям огромный, то всё ок.
Автор решения: Андрей Коробейников
→ Ссылка
Я бы предложил немного другое решение, при условии что я вообще верно понял суть задачи , что можно редактировать исходный класс 'users' и добавлять свои классы.
Примерно так :
# имя класса пишется в камелкейс (UsersList, OrderedDict)
class User:
def __init__(self, name, gorod, ulica):
self.name = name
self.gorod = gorod
self.ulica = ulica
@property
def address(self):
return (self.gorod, self.ulica)
def __str__(self):
return f"{self.name:<15} {self.gorod:<15} {self.ulica:<15}"
# создадим свой класс, отнаследованный от list
class UsersList(list):
def append(self, obj: User):
"""
Переопределим стандартный метод класса list, так что бы при
добавлении очередного пользователя проверялся есть ли уже такой адрес и если есть то вносились необходимые изменения в адрес
"""
if not isinstance(obj, User):
print(f"UserList can append User class only, not {type(obj)}")
if count := self.count_address(obj):
if count == 1:
o = self.get_by_address(obj.address)
o.ulica = f"{obj.ulica}_{count}"
obj.ulica = f"{obj.ulica}_{count+1}"
super().append(obj)
def count_address(self, obj:User):
index = 0
for o in self:
if obj.address[0]==o.address[0] and obj.address[1] in o.address[1]:
index += 1
return index
def get_by_address(self, address:tuple) -> User:
for o in self:
if address[0]==o.address[0] and address[1] in o.address[1]:
return o
# не стоит давать имя переменным, которое уже занять встроенными объектами (типа list, dict, etc)
ls = UsersList()
ls.append( User('Иван', 'Москва', 'Ленина') )
ls.append( User('Андрей', 'Москва', 'Ленина') )
ls.append( User('Андрей', 'Москва', 'Маяковского') )
ls.append( User('Артём', 'Ростов', 'Горького') )
ls.append( User('Анна', 'Астрахань', 'Петрова') )
ls.append( User('Артём', 'Астрахань', 'Петрова') )
for user in ls:
print(user)
Если необходимо, можно так же переопределить метод extend. А так задачу считаю решенной. Вывод в консоль следующий:
Иван Москва Ленина_1
Андрей Москва Ленина_2
Андрей Москва Маяковского
Артём Ростов Горького
Анна Астрахань Петрова_1
Артём Астрахань Петрова_2