Toolz Это чрезвычайно полезная коллекция функций утилиты, которая может помочь вам делать то, что вы делаете все время, но более явно и часто с меньшим количеством кода.
Я собираюсь выделить несколько функций, которые я использую больше всего, но есть много других, и все они твердое золото.
Дал оригинал дикта
:
original = { 'A': 1, 'B': 2, 'C': 3, }
Фильтровать элементы по ключу
Чтобы создать новый дикта
от оригинал
При исключении элемента с key = 'c'
, без инструмент
, Я бы, наверное, сделал:
new = { k: v for k, v in original.items() if k != 'C' }
Используя dicttoolz.keyfilter , это становится:
new = keyfilter(lambda k: k != 'C', original)
Что мне действительно нравится в этом KeyFilter
Решение, помимо того, что быть более кратким, функциональным и т. Д., Это то, что его имя ясно говорит вам, что происходит.
Фильтрация элементов по значению
Учитывая вспомогательную функцию под названием is_even
это возвращает Bool
Указывая, является ли единственный числовой аргумент ровным:
is_even = lambda x: x % 2 == 0
Или, как не Lambda
:
def is_even(x): return x % 2 == 0
Чтобы создать новый дикта
от оригинал
Включая только равномерные значения, без инструмент
, Я бы, наверное, сделал:
new = { k: v for k, v in original.items() if is_even(v) }
Используя dicttoolz.valfilter , это становится:
new = valfilter(is_even, original)
Дал список дикта
S представляет пользователей:
users = [ { 'name': 'User A', 'age': 30, }, { 'name': 'User B', 'age': 32, }, { 'name': 'User C', 'age': 41, }, { 'name': 'User D', 'age': 43, }, ]
Получить только возраст, без инструмент
, Я сделаю:
ages = [ user['age'] for user in users ]
Используя itertoolz.pluck , это становится:
ages = pluck('age', users)
Обратите внимание, что это ^ (как и некоторые другие функции Toolz ) фактически возвращает
генератор -type itertools.imap объект, который в порядке, если вы собираетесь перевернуть его, Но если вы хотите индексировать это, как
возраст [0] , вам нужно преобразовать его в список (или кортеж):
>>> ages[0] TypeError: 'itertools.imap' object has no attribute '__getitem__' >>> ages = list(pluck('age', users)) >>> ages[0] 30
Вы также можете Перекачивать
несколько ключей одновременно, указав их в список:
age_name_pairs = pluck(['age', 'name'], users)
Что выглядит как:
>>> list(age_name_pairs) [(30, 'User A'), (32, 'User B'), (41, 'User C'), (43, 'User D')]
Учитывая тот же список пользователя дикта
s, как раньше:
users = [ { 'name': 'User A', 'age': 30, }, { 'name': 'User B', 'age': 32, }, { 'name': 'User C', 'age': 41, }, { 'name': 'User D', 'age': 43, }, ]
Если я хотел группировать пользователей в возрастные группы по разрешению десятилетия (то есть 30-е, 40-е годы и т. Д.), Без инструмент
Может, я бы сделал что -то вроде:
age_decade_users_map = defaultdict(list) for user in users: age_decade = int(user['age'] / 10) * 10 age_decade_users_map[age_decade].append(user)
Это производит:
>>> dict(age_decade_users_map) {30: [{'age': 30, 'name': 'User A'}, {'age': 32, 'name': 'User B'}], 40: [{'age': 41, 'name': 'User C'}, {'age': 43, 'name': 'User D'}]}
Используя itertoolz.groupby , это может быть достигнуто с помощью:
age_decade_users_map = groupby( lambda user: int(user['age'] / 10) * 10, users )
Почетное упоминание идет:
itertoolz.first – Получите первый элемент от итерабильного (даже
set
s!)itertoolz.partitional_all – Разделите итерабируемые на кортежи указанной максимальной длины
dicttoolz.assoc – Получите копию DICT с добавленным указанным элементом
dicttoolz.dissoc – Получите копию DICT с удаленными указанными клавишами (аналогично по функции с моим
dicttoolz.get_in
– как dict.get ()
Но при поддержке многократных ключей, например,
get_in ([‘a’, ‘b’], {‘a’: {‘b’:
Счастлив Toolz
Удачно!
Оригинал: “https://dev.to/derekenos/python-charming-with-toolz-4bf2”