Сочетание methodcaller и attrgetter с отсортированным - PullRequest
0 голосов
/ 06 мая 2018

Я хочу получить список объектов PosixPath и отсортировать его по размеру соответствующего файла. Я пытаюсь сделать это с помощью отсортированной функции. Ключ, который я хочу использовать для сортировки: object.stat().st_size, где объект - это объект PosixPath, stat() возвращает объект os.stat_result, а st_size - размер файла, соответствующего объекту PosixPath. Я знаю, как сортировать на основе метода объекта или атрибута объекта, используя operator.methodcaller или operator.attrgetter, но я не могу понять, как использовать атрибут объекта, возвращаемый methodcaller.

Я попробовал следующее и некоторые варианты, но это не работает:

from operator import attrgetter, methodcaller
from pathlib import Path

sorted(Path('my_directory').glob('*.extension'), key=methodcaller('stat').st_size)

Ответы [ 2 ]

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

Состав функции не является родным в Python.

Один читаемый способ применить вашу логику - использовать прямой, а не функциональный маршрут:

res = sorted(Path('.').glob('*.py'), key=lambda p: p.stat().st_size)

Однако есть сторонние библиотеки, которые предлагают эту функцию, такие как toolz:

from toolz import compose
from operator import attrgetter, methodcaller

get_size = compose(attrgetter('st_size'), methodcaller('stat'))

res = sorted(Path('.').glob('*.py'), key=get_size)

По моему мнению, если вы хотите функциональное решение, вы должны использовать или написать композиционную функцию более высокого порядка, такую ​​как приведенная выше, чтобы обеспечить читабельность вашего кода.

Похожие: Вложенные лямбда-выражения при сортировке списков

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

Они не предназначены для объединения. Вы должны использовать лямбду в качестве ключа:

from pathlib import Path
sorted(Path('.').glob('*.py'), key=lambda p: p.stat().st_size)

Или, если вы хотите динамически изменить поле сортировки:

key_field = 'st_mtime'
sorted(Path('.').glob('*.py'), 
       key=lambda p: attrgetter(key_field)(p.stat()))

И, если вы действительно хотите использовать methodcaller и attrgetter, вы можете сделать:

sorted(Path('.').glob('*.py'), key=lambda p: attrgetter('st_size')(methodcaller('stat')(p)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...