Удаление пар из списка в python

#python #python-3.x

#python #python-3.x

Вопрос:

Предположим, у меня есть список a = ["1a", "1b", "2b", "3c", "2d", "1g", "3d", "3g"] , и я хочу удалить все пары элементов, которые имеют одинаковый коэффициент / начальный символ в элементе, так что он дает ответ типа ["1g", "3g"] .

Как бы я мог это сделать?

Это то, чего я достиг до сих пор, но это беспорядок и функционирует не совсем хорошо

 def pairs(l):

    for x in range(len(l) -1,-1,-1):
        counter=0
        z=l[x][0]
        for f in range(len(l)-1,-1,-1):
            if z==(l[f][0]):
                counter =1
        if counter%2==0:
            for i in range(x,x-1,-1):
                if z==(l[i][0]):
                   del (l[i])
        elif counter%2==1 :
            for i in range(x-1,x-2,-1):
                if z==(l[i][0]):
                    del (l[i])

    print(l)
  

Комментарии:

1. Я не понимаю, как вы получили свой пример ответа. Почему в ответе «3g», когда он разделяет ведущий символ со своим соседом «3d»?

2. Не могли бы вы немного подробнее объяснить, почему [«1g», «3g»] является вашим желаемым ответом. Почему не 1a или 1b или 3c?

3. @Kevin Есть три элемента с первым индексом «3», удаление пар оставит только один элемент, который в моем примере «3g». Также имейте в виду, что оставшийся элемент необязательно должен быть «3g», это может быть «3c» или «3d». Извините, если это было недостаточно ясно

4. @A.Kot Извините, если я недостаточно ясно выразился, да, если элементы встречаются нечетное количество раз, любой элемент может быть оставшимся, в моем примере я выбрал «1g» и «3g», но это мог быть любой другой элемент с тем же первым индексом, например «1a» и «1b» вместо «1g» и «3c» и «3d» вместо «3g».

Ответ №1:

 a = ["1a", "1b", "2b", "3c", "2d", "1g", "3d", "3g"]

coeffs = [a[0][0]] # collect coefficients
for i in a[1:]:
  if i[0] not in coeffs: coeffs.append(i[0])

s = [[x for x in a if x[0] == i] for i in coeffs] # groups according to coefficients
# s = [["1a", "1b", "1g"], ["2b", "2d"], ["3c", "3d", "3g"]]

solution = [i[-1] for i in s if len(i)%2]
# ['1g', '3g']
  

Комментарии:

1. Не могли бы вы подробнее объяснить пятую строку предоставленного вами кода. Спасибо, это было очень полезно.

2. это сгруппирует элементы в соответствии с коэффициентами. Я обновил комментарий в своем ответе о том, как будет выглядеть сгруппированный список.

Ответ №2:

Вы можете сгруппировать элементы списка на основе первого символа, а затем исключить пары. Для этого itertools.groupby() может пригодиться:

 >>> a = ["1a", "1b", "2b", "3c", "2d", "1g", "3d", "3g"]
>>> a.sort()
>>> from itertools import groupby
>>> result = []
>>> for x, y in groupby(a, lambda x: x[0]):
...     y = list(y)
...     if len(y) % 2:
...         result.append(y[-1])
... 
>>> result
['1g', '3g']
  

Ответ №3:

 def deleter(char,seq):
    if not seq or not isinstance(seq, list):
        return []
    else:
        if char==seq[0][0]:
            return function(char,seq[1:])
        else:
            return [seq[0]] function(char,seq[1:])
  

Я бы решил это, используя рекурсивное определение:

  • Базовый вариант: если seq значение пусто, возвращается пустой список
  • Проверьте случай: если его элемент с индексом 0 является символом, который мы ненавидим, тогда игнорируйте его.
  • Решение: else return the first element in the list seq in a form of list and add to it the call of function itself

РЕДАКТИРОВАТЬ: У меня такое чувство, что вы начинающий программист, если это так, я просто хочу подчеркнуть кое-что о красоте и элегантности рекурсивных функций. Это элегантный математический способ решения проблем. Ваш код будет в значительной степени легко читаем как начинающими программистами, так и бывшими программистами и математиками, если они хоть немного знакомы с доказательством по указанию в дискретной математике. В большинстве случаев вы в основном следуете следующему псевдокоду:

  • Базовый вариант: условие для завершения вашей функции
  • Оператор Return: Вы возвращаете рекурсивный вызов функции Способ, которым я визуализирую рекурсию, заключается в том, что у вас есть проблема, которую нужно решить, вы предполагаете, что создали функцию, которая решает проблему (базовый вариант), теперь вы вызываете функцию для решения вашей проблемы (возвращаете вызов функции)

Ответ №4:

Это не должно быть чрезмерно сложным. Сопоставьте слова по их начальным символам, но вместо этого удалите существующий элемент, если в словаре уже есть этот ключ.

 def pairs(a):

    result = {}
    for word in a:
        leading_char = word[0]
        if result.has_key(leading_char):
            del result[leading_char]
        else:
            result[leading_char] = word

    return result.values()

a = ["1a", "1b", "2b", "3c", "2d", "1g", "3d", "3g"]
print pairs(a)