Сортировка словаря python по слотам с равными интервалами

#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]}