Пары на дикте (Python) - PullRequest
       5

Пары на дикте (Python)

1 голос
/ 17 апреля 2020

У меня есть диктат с идентификатором и случайно сгенерированным возрастом. Например (случайный возраст):

json = {0: {'age': 14},
        1: {'age': 23},
        2: {'age': 43},
        3: {'age': 29}

У меня есть диапазон. Например, [5; 20]. Я хочу запустить массив следующим образом:

0->1, 0->2, 0->3   #FIX
1->2, 1->3
2->3

И я хочу проверить, соответствует ли он условию 5 < abs(n-m) < 20.

1). 0 с 1:

if 5 < abs(json[0]['age']-json[1]['age']) < 20:
    pass

2). 0 с 2:

if 5 < abs(json[0]['age']-json[2]['age']) < 20:
    pass

n). n с m:

if 5 < abs(json[n]['age']-json[m]['age']) < 20:
    pass

Так что все они должны находиться в пределах досягаемости друг друга. На самом деле, есть несколько диапазонов, но я думаю, что одного достаточно для примера. Я не очень понимаю, как это может быть реализовано в Python, пожалуйста, помогите. Может быть, это поможет:

don't judge the image strictly

введите описание изображения здесь

Ответы [ 3 ]

0 голосов
/ 17 апреля 2020

Подход кода должен выглядеть примерно так:

def checkRange(bottom, top, data):
  lastkey=list(data.keys())[-1]
  for key in data.keys():
    for x in range(key+1, lastkey+1):
      if bottom<abs(data[key]['age']-data[x]['age']) < top:
        pass
      else: 
        print(key, x)

data = {0: {'age': 14},
    1: {'age': 23},
    2: {'age': 43},
    3: {'age': 29}}

checkRange(5,20,data)

Вместо печати или передачи вы можете выбрать, что делать!

0 голосов
/ 17 апреля 2020

Я думаю, itertools.combinations специально для этой цели. Вы можете подробно прочитать документацию: itertools

В вашем случае вы можете позвонить по этому номеру:

import itertools as it
a=list(it.combinations(json,2))

Если вы печатаете a, вы можете четко посмотрите комбинацию нужного вам индекса:

[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)] # print (a)
# what you want
0->1, 0->2, 0->3   #FIX
1->2, 1->3
2->3

Затем вычислите и выведите абсолютную разницу между двумя элементами:

for item in a:
    print (abs(json[item[0]]['age']-json[item[1]]['age']) )

Вывод:

9
29
15
20
6
14

Кроме того, вы можете сократить коды и проверить диапазон:

for i in it.combinations(json,2):
    v=abs(json[i[0]]['age']-json[i[1]]['age'])
    if v in range(5+1,20):
        pass
    else:
        print ('False',i,'age:',v )

Выход:

False (0, 2) age: 29
False (1, 2) age: 20
0 голосов
/ 17 апреля 2020

Это можно сделать с помощью одной строки, используя любой диапазон, который вы хотите проверить:

range_check = range(5, 21)  # Range second arg is exclusive
# Get answer as a bool value
res = all(abs(json[i]['age'] - json[j]['age']) in range_check
           for i in range(len(json)) for j in range(i-1, -1, -1))

Конечно, это предполагает, что ваш dict построен, как в примере, где ключ каждый элемент является его индексом.

Для более общего подхода, который будет работать независимо от ключей, вы можете сохранить ключи в виде кортежа или списка:

range_check = range(5, 21)  # Range second arg is exclusive
keys = tuple(json.keys())
# Get answer as a bool value
res = all(abs(json[key1]['age'] - json[key2]['age']) in range_check
           for i, key1 in enumerate(keys) for key2 in keys[:i])
print(res)
...