#python #sorting #dictionary
Вопрос:
Как мы можем сортировать словарь на основе ключей словаря и распределять их по последовательным интервалам?
Например, у нас есть следующий словарь на python
{0: 1, 10: 3, 12: 2, 19: 4, 35: 5}
Итак, в приведенном выше примере у нас есть ключи , от которых мы отбираем 0 - 35
, и мы хотим расположить их с интервалом в 10, что подразумевает следующее:
interval 0-10 has values 1 interval 10-20 has values [3, 2, 4] interval 20-30 has no values interval 30-40 has values [5]
Конечный результат должен быть похож на этот:
{0: [1], 10: [3, 2, 4], 20: [0/null], 30: [5]
Есть какой-нибудь питонический способ сделать это?
Комментарии:
1. @PedroMaia Я не был уверен, как получить интервалы в качестве ключей, но ваше решение на месте. Если это
two-digit
число, мы можем разделить его на10
, что даст нам первое целое число, а затем умножить на10
. Понравилась твоя идея, спасибо2. @PedroMaia, если мы хотим включить недостающие интервалы в окончательный вывод. Давайте скажем здесь:
20: [0 or null]
. Один из способов, о котором я мог бы подумать, — как только мы получим вывод, снова пройдемся по ключам словаря и найдем недостающие значения? Можем ли мы сделать это лучше?
Ответ №1:
С помощью collections.defaultdict
:
from collections import defaultdict data = {0: 1, 10: 3, 12: 2, 19: 4, 35: 5} output = defaultdict(list) for k, v in data.items(): output[k // 10 * 10].append(v)
gt;gt;gt; dict(out) {0: [1], 10: [3, 2, 4], 30: [5]}
Редактировать
Если у вас должны быть все ключи в результирующем дикте, замените дикт по умолчанию на дикт, который сам создает ключи:
out = {k: [] for k in (range(0, (max(data)//10*10) 1, 10))} for k, v in data.items(): out[k // 10 * 10].append(v)
Комментарии:
1. спасибо, @Jab, есть ли способ включить пустые интервалы в одну и ту же итерацию без второго цикла?
2. Пожалуйста, посмотрите мою правку.
3. Так будет лучше.
4. Я предполагаю, что его
max(data)//10 * 10
5. Нет … Это должно быть так, чтобы это соответствовало нужному количеству, но у этого есть конечные случаи, поэтому, чтобы быть правильным, это было бы:
(max(data) // 10 * 10) 1
Ответ №2:
Чтобы добавить пропущенные значения, возможно, сохраните переменную с последним и проверьте, не превышает ли разрыв между ними 10:
a = {0: 1, 10: 3, 12: 2, 19: 4, 35: 5} out = {} last = 0 for i in a: b = int(i/10) * 10 if (b - last) gt; 10: out[b-10] = [] # whatever you want it to be if b in out: out[b].append(a[i]) else: out[b] = [a[i]] last = b
Выход:
{0: [1], 10: [3, 2, 4], 20: [], 30: [5]}
Комментарии:
1. круто, но все же еще одна проверка. Если у нас есть следующие входные данные:
{0: 1, 10: 3, 12: 2, 19: 4, 45: 5}
, то вывод будет{0: [1], 10: [3, 2, 4], 30: [], 40: [5]}
, но не{0: [1], 10: [3, 2, 4], 20: [], 30:[], 40: [5]}