Я использую этот API https://jsonplaceholder.typicode.com/posts, чтобы перечислить все сообщения, подобные этому,
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
},
Мой код,
session = requests.Session()
payload = session.request("GET", "https://jsonplaceholder.typicode.com/posts", timeout = 30).json()
print(payload)
Теперь я хотел отсортировать все объекты по id
,
d = sorted(payload, key=operator.itemgetter("id"))
print(d)
Теперь, если я хочу сортировать по длине заголовка,
Я не знаю, как использовать operator
для предоставления len(title)
качестве ключа, возможно ли это?
Используя выражение генератора с циклом for
вместо key
,
d = sorted(len(value["title"]) for value in payload)
print(d)
Выход,
[12, 12, 14, 14, 15, 18, 20, 20, 20, 20, 23, 24, 24, 24, 24, 24, 24, 25, 25, 26, 26, 26, 27, 27, 29, 29, 29, 30, 30, 30, 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35, 36, 37, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 45, 46, 47, 47, 47, 49, 50, 50, 51, 51, 53, 53, 53, 53, 54, 55, 55, 55, 57, 59, 60, 60, 67, 68, 72, 74, 76, 76, 78, 79]
Как вы можете видеть, это дает мне длину каждого title
, но я не знаю настоящего названия. Как я могу напечатать title
вместе с его длиной для каждого объекта json?
Используйте lambda
для указания специального критерия сортировки:
d = sorted(payload, key=lambda x: len(x['title']))
print(d)
В официальной документации есть пример сортировки с lambda
здесь: https://docs.python.org/3/howto/sorting.html#key-functions
Затем, чтобы печатать названия и их длины, вы можете сделать что-то вроде:
titles = [(p['title'], len(p['title'])) for p in sorted(payload, key=lambda x: len(x['title']))]
print(titles)
>>> [('qui est esse', 12), ('sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 74)]
Это можно сделать в три этапа:
1) название выписки
2) сортировать по len
3) строить пары
Это все еще удобно подходит для одной линии и на самом деле вполне читаемо:
[(x, len(x)) for x in sorted((x['title'] for x in mock), key=len)]
Прогон образца
[('jfzq', 4), ('uqixc', 5), ('xparg', 5), ('uvuuk', 5), ('gsibnde', 7), ('pophwash', 8), ('cudisvgf', 8), ('swptewjg', 8), ('rthjtjylh', 9), ('ezvwpqhfn', 9)]
Код для создания mock
данных:
>>> from random import choices, randint
>>> from string import ascii_lowercase
>>>
>>> mock = [{k: ''.join(choices(ascii_lowercase, k=randint(4, 10))) for k in ('userId', 'id', 'title', 'body')} for _ in range(10)]
key=
sorted
. какsorted(payload, key = lambda x: len(x['title']))
.