эффективное сравнение значений в списке Python - PullRequest
1 голос
/ 06 февраля 2011

У меня есть список, составленный из кортежей, таких как приведенный ниже:

(2809.3994479562093, 1032.5989696312365, 0.0), {'level': '2', 'id': '1'})

имея набор различных значений для ключа уровня в словаре (увеличивая, но не всегда целые числа, то есть 1, 2, 3, 3B, 4A, 5, 5A, 6, 7), идентификатор увеличивается постепенно и состоит только из целых чисел.

То, что я пытаюсь выяснить, это значение первых двух значений в первом элементе кортежа, то есть с плавающей запятой 2809.399 ... и 1032.5989 ... в случае уровня +/- 1 отличается от тех, на которых я сейчас нахожусь. Другими словами, уровень 2 id 1 должен искать идентификатор 1 на уровнях 1 и 3.

Вот что я придумал для этого:

for x in xrange(len(net.lifts)):
    if net.lifts[x][1]["level"] == "2":
        for y in xrange(len(net.lifts)):
            if (net.lifts[y][1]["level"] == "1" or net.lifts[y][1]["level"] == "3") and net.lifts[y][1]["id"] == net.lifts[x][1]["id"]:
                print "edge:" + str(net.lifts[x][0][:2]) + str(net.lifts[y][0][:2])

и это работает. Однако это требует от меня определения длинных операторов if для каждого случая. Есть ли более эффективный способ (алгоритм) абстрагирования этого без создания 7 циклов if (по одному на каждый уровень)?

Ответы [ 2 ]

2 голосов
/ 06 февраля 2011

Две ноты:

  1. Вы не пишете for i in range(len(xs)): # use xs[i] на Python, равно как вы не пишете int i = 0; while (i < N) { /* use xs[i]; */ i++; } на C. Вы пишете for x in xs: # use x.
  2. Попробуйте использовать с именем tuple для описательных имен для значений. Также рассмотрите возможность реструктуризации данных. Например, вы можете использовать следующий формат: { level_1: { id_1: (val_1, val_2), id_2: ...}, level_2: ...}.

Что касается самой проблемы: вы можете обобщить ее даже с текущим форматом (обратите внимание, что в коде предполагается, что уровни целые - я знаю, что это не так, но я не знаю, как вы переходите с одного уровня на следующий в вашей системе тоже).

for lift in net.lifts:
    for other_lift in net.lifts:
        if (lift[1]['id'] == other_lift[1]['id'] and
            abs(lift[1]['level'] - other_lift[1]['level']) <= 1):
            # got one

Было бы проще (и быстрее, сложнее - сейчас это O(n**2)) с более продуманными структурами данных.

1 голос
/ 06 февраля 2011

Вы должны реструктурировать свои данные.Формат, в котором он находится в данный момент, не способствует решению проблемы, которую вы пытаетесь решить, поскольку он имеет последовательную форму, и вы фактически пытаетесь сделать произвольный доступ, как в словаре.

Перегруппируйте его в словарь:

'level':
    'id':
        (data)

Другая проблема заключается в том, что вам нужно определить, что значит быть "+/- 1 от уровня, на котором вы находитесь", если ваши уровни не являются целыми числами.То есть, что на один уровень выше 3 сказать?3B, 4A, 4B, ...?Чтобы решить эту проблему, вы, вероятно, захотите переопределить свои уровни, чтобы они были целыми числами, и сохраните отображение от имени строки до целочисленного значения.Целые числа являются хорошим типом данных для хранения уровней.

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