Как сравнить и извлечь определенные элементы из списка в Python? - PullRequest
0 голосов
/ 14 мая 2018

Есть список, содержащий информацию о файлах.

tables = ["20180512, name=file01, size=100",
          "20180512, name=file02, size=90",
          "20180513, name=file01, size=70",
          "20180513, name=file02, size=70",
          "20180513, name=file03, size=80",
          "20180514, name=file01, size=100",
          "20180514, name=file02, size=90"]

Я хочу сделать словарь с самым большим предметом каждого дня. Таким образом, с этим списком словарь будет

dic_table = {20180512:file01,
             20180513:file03,
             20180514:file01}

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

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

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

Идея состоит в том, чтобы отсортировать, сгруппировать и затем использовать словарь:

from itertools import groupby
from operator import itemgetter

def tupler(x):
    a = x.split(',')
    b = a[1].split('=')[-1]
    c = a[2].split('=')[-1]
    return int(a[0]), b, int(c)

# sort by date and then by size descending
sorter = sorted(map(tupler, tables), key=lambda x: (x[0], -x[2]))

# group by date
grouper = groupby(sorter, key=itemgetter(0))

# extract first item in groups and remove size from result
res = dict(list(j)[0][:-1] for i, j in grouper)

print(res)

{20180512: 'file01',
 20180513: 'file03',
 20180514: 'file01'}
0 голосов
/ 14 мая 2018

Библиотека pandas идеально подходит для этой задачи:

Во-первых, измените ваши данные, чтобы они могли легко помещаться в информационный фрейм, удалив size= и name=, а также ненужные пробелы:

import re
import pandas as pd
tables = [re.sub(r'(\w+=|\s+)', '', i).split(',') for i in tables]

# [['20180512', 'file01', '100'],
# ['20180512', 'file02', '90'],
# ['20180513', 'file01', '70'],
# ['20180513', 'file02', '70'],
# ['20180513', 'file03', '80'],
# ['20180514', 'file01', '100'],
# ['20180514', 'file02', '90']]

Затем преобразовать в фрейм данных:

df = pd.DataFrame(tables, columns=['Date', 'Name', 'Size'])

#        Date     Name  Size
# 0  20180512   file01   100
# 1  20180512   file02    90
# 2  20180513   file01    70
# 3  20180513   file02    70
# 4  20180513   file03    80
# 5  20180514   file01   100
# 6  20180514   file02    90

Наконец, мы можем использовать groupby и idxmax(), чтобы получить наши максимальные значения, и zip, чтобы преобразовать в словарь:

df['Size'] = df['Size'].astype(int)
maxes = df.iloc[df.groupby('Date').Size.idxmax()]

#           Date    Name  Size
#    0  20180512  file01   100
#    4  20180513  file03    80
#    5  20180514  file01   100

print(dict(zip(maxes.Date.values, maxes.Name.values)))

#  {'20180512': 'file01', '20180513': 'file03', '20180514': 'file01'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...