Как удалить элементы словаря в списке на основе значений в строке - PullRequest
0 голосов
/ 16 апреля 2019

Я занят извлечением данных с помощью Python 2.7. До сих пор я получил список со словарями в качестве элементов.В течение 2 дней я не могу получить больше с этим.

Данные:

list = [
    {
        'displayName': '#12',
        'timestamp': 1543588481684,
        'number': 12,
        'result': 'SUCCESS',
        'fullDisplayName': 'Configs \xbb Virtual Host #12'
    },
    {   
        'displayName': '#64',
        'timestamp': 1544432646765,
        'number': 64,
        'result': 'SUCCESS',
        'fullDisplayName': 'Configs \xbb Development Virtual Host Deploy #64'
    },
    {
        'displayName': '#15',
        'timestamp': 1544432258338,
        'number': 15,
        'result': 'SUCCESS',
        'fullDisplayName': 'Configs \xbb Virtual Host #15'
    },
    {   
        'displayName': '#61',
        'timestamp': 1554186520499,
        'number': 61,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb release/1.0.0 #61'
    },
    {   
        'displayName': '#5',
        'timestamp': 1554274310468,
        'number': 5,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb release/1.0.2 #5'
    },
    {   
        'displayName': '#1',
        'timestamp': 1554289674392,
        'number': 1,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb release/1.0.3 #1'
    },
    {   
        'displayName': '#1',
        'timestamp': 1554290695120,
        'number': 1,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb release/1.0.4 #1'
    },
    {   'displayName': '#1',
        'timestamp': 1554292855198,
        'number': 1,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb release/1.0.5 #1'
    },
    {   
        'displayName': '#1',
        'timestamp': 1554381545158,
        'number': 1,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb release/1.0.7 #1'
    },
    {   'displayName': '#2',
        'timestamp': 1554191277415,
        'number': 2,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb tag/1.0.0 #2'
    },
    {   'displayName': '#6',
        'timestamp': 1554212133716,
        'number': 6,
        'result': 'FAILURE',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb tag/1.0.1 #6'
    }
]

Я хочу удалить элементы словаря в списке, где 'fullDisplayName' содержит ('hotfix', 'tag'), но сохранить последний элемент списка (словарьс наибольшим значением версии (hotfix / 1.0.?)).

Ожидаемый результат:

list = [
    {
        'displayName': '#12',
        'timestamp': 1543588481684,
        'number': 12,
        'result': 'SUCCESS',
        'fullDisplayName': 'Configs \xbb Virtual Host #12'
    },
    {   
        'displayName': '#64',
        'timestamp': 1544432646765,
        'number': 64,
        'result': 'SUCCESS',
        'fullDisplayName': 'Configs \xbb Development Virtual Host Deploy #64'
    },
    {
        'displayName': '#15',
        'timestamp': 1544432258338,
        'number': 15,
        'result': 'SUCCESS',
        'fullDisplayName': 'Configs \xbb Virtual Host #15'
    },
    {   
        'displayName': '#1',
        'timestamp': 1554381545158,
        'number': 1,
        'result': 'SUCCESS',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb release/1.0.7 #1'
    },
    {   'displayName': '#6',
        'timestamp': 1554212133716,
        'number': 6,
        'result': 'FAILURE',
        'fullDisplayName': 'Docker \xbb Configs Deploy \xbb tag/1.0.1 #6'
    }
]

Надеюсь, кто-то может указать мне правильное направление.

Спасибо

Ответы [ 4 ]

1 голос
/ 16 апреля 2019
  1. искать нужные ключевые слова
  2. проверить для более высоких версий
  3. при необходимости удалить элемент

Псевдокод:

for item in list:
    if dictContainsKeyword(item, "hotfix") or dictContainsKeyword(item, "tag"):
        if listContainsNewerVersion(list, item):
            removeDictFromList(list, item)

Для dictContainsKeyword, listContainsNewerVersion и removeDictFromList необходимо выбрать атрибут словаря, который имеет уникальные значения. Или используйте набор атрибутов для идентификации одного словаря.

В listContainsNewerVersion вы можете перебирать список и сравнивать словари с заданными.

РЕДАКТИРОВАТЬ: изменено на для каждого цикла, чтобы избежать проблем с итерацией списка и удалением объектов.

0 голосов
/ 16 апреля 2019

Предполагается, что наш оригинал называется my_list, а значения, которые нам нужно ограничить, хранятся в restricted

my_list = [
    {
        'displayName': '#12',
        'timestamp': 1543588481684,
        'number': 12,
        'result': 'SUCCESS',
        'fullDisplayName': 'Configs \xbb Virtual Host #12'
    },
    ...
]
restricted = ['hotfix','tag']

Сначала нам нужно найти словарь с наибольшим числом, мы будем использовать max() и установите key, чтобы найти словарь на основе наибольшего значения ['number'].

highest = max(my_list, key=lambda x: x['number'])

Мы могли бы использовать встроенную функцию Python filter() для фильтрации определенныхсловари.Для этого мы определим функцию, которая будет определять, является ли некоторый словарь действительным или нет, здесь my_filter().

def my_filter(x):
    # check if provided dict is one with the highest value
    if x == highest:
        return True

    # check if ['fullDisplayName'] doesn't contains any of resticted words
    if not any(i in x['fullDisplayName'] for i in restricted):
        return True

    return False

new_list = list(filter(my_filter, my_list))

Или с функцией фильтра в виде лямбды в одной строке

new_list = list(filter(lambda x: x==highest or not any(i in x['fullDisplayName'] for i in restricted), my_list))
0 голосов
/ 16 апреля 2019

Сделайте что-то вроде этого:

new_list = []
append_last = (0, None)
for index, obj in enumerate(list):
    if 'hotfix' in obj['fullDisplayName'] or 'tag' in obj['fullDisplayName']:
        number = int("tag/1.0.1".split('/')[1].replace('.',''))
        append_last = (number, index) if append_last[0] < number else append_last
    else:
        new_list.append(obj)
if append_last[1]:
    new_list.append(list[append_last[1]])
print new_list
0 голосов
/ 16 апреля 2019

Вы можете попробовать что-то вроде нижеприведенного подхода, не очень эффективного, но это решит вашу проблему

>>> list1 = [i for i in list if 'tag' not in i['fullDisplayName']]
>>> list2 = [i for i in list if 'tag' in i['fullDisplayName']]
>>> from operator import itemgetter
>>> newlist = sorted(list2, key=itemgetter('displayName'), reverse=True)
>>> list1.append(newlist[0])
...