Сравните значения словаря для каждого ключа в том же словаре в Python - PullRequest
1 голос
/ 24 мая 2011

Обновление:

Здравствуйте еще раз.У меня вопрос, как я могу сравнить значения словаря на равенство.Подробнее о моем словаре:

  • ключи - это номера сеансов
  • значения каждого ключа - это вложенные списки -> fe

    [[1,0], [2,0], [3,1]]

  • длина значений для каждого ключа не одинакова, поэтому может быть так, что номер сеанса 1 имеет больше значений, чем номер сеанса2

  • вот пример словаря:

order_session = {1: [[100,0], [22,1], [23,2]], 10: [100,0], [232,0], [10,2], [11,2]], 22: [[5,2], [23,2], ....],...}

Моя цель:

Шаг 1 : сравнить значения номера сеанса 1 со значениями всех других номеров сеанса всловарь на равенство

Шаг 2 : взять следующий номер сеанса и сравнить его с другими значениями других номеров сеансов и т. д. - наконец, мы сравниваем каждое значение номера сеанса

Шаг 3 : сохранить результат в список, например: output = [[100,0], [23,2], ...] или output = [(10)0,0), (23,2), ...]

  • , если вы видите, что пары значений [100,0] сеанса 1 и 10 совпадают.также пара значений [23,2] сеансов 1 и 22 одинакова.

Спасибо за помощь.

Обновление 2

Спасибо за вашу помощь и советы по превращению вложенного списка списков в список кортежей, которые лучше с ним справляются.

Я предпочитаю решение Boaz Yaniv;) Мне также нравится использованиеof collection.Counter () ... не повезло, что я использую 2.6.4 (Counter работает на 2.7), может быть, иногда я перехожу на 2.7.

Ответы [ 4 ]

2 голосов
/ 24 мая 2011

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

def get_repeated_values(sessions):
    known = set()
    already_repeated = set()
    for lst in sessions.itervalues():
        session_set = set(tuple(x) for x in lst)
        repeated = (known & session_set) - already_repeated
        already_repeated |= repeated
        known |= session_set
        for val in repeated:
            yield val

sessions = {1:[[100,0],[22,1],[23,2]],10:[[100,0],[232,0],[10,2],[11,2]],22:[[5,2],[23,2]]}
for x in get_repeated_values(sessions):
    print x

Я также предлагаюопять же, из соображений производительности) вкладывать кортежи в свои списки вместо списков, если вы не собираетесь изменять их «на лету».Код, который я разместил здесь, будет работать в любом случае, но будет быстрее, если значения уже являются кортежами.

0 голосов
/ 24 мая 2011
order_session = {1:[[100,0],[22,1],[23,2]],10:[[100,0],[232,0],[10,2],[11,2]],22:[[5,2],[23,2],[80,21]],}
output = []
for pair in sum(order_session.values(), []):
    if sum(order_session.values(), []).count(pair) > 1 and pair not in output:
        output.append(pair)

print output
...
[[100, 0], [23, 2]]
0 голосов
/ 24 мая 2011
>>> from collections import Counter
>>> D = {1:[[100,0],[22,1],[23,2]],
... 10:[[100,0],[232,0],[10,2],[11,2]],
... 22:[[5,2],[23,2]]}
>>> [k for k,v in Counter(tuple(j) for i in D.values() for j in i).items() if v>1]
[(23, 2), (100, 0)]

Если вам действительно нужен список списков

>>> [list(k) for k,v in Counter(tuple(j) for i in D.values() for j in i).items() if v>1]
[[23, 2], [100, 0]]
0 голосов
/ 24 мая 2011

Вероятно, есть более хороший и более оптимальный способ сделать это, но я бы поработал так:

seen = []
output = []

for val in order_session.values():
    for vp in val:
        if vp in seen:
            if not vp in output:
                output.append(vp)
        else:
            seen.append(vp)

print(output)

В основном, это то, что это делает, чтобы просмотреть все значения, и еслизначение было замечено ранее, но не выводилось ранее, оно добавляется к выводу.

Обратите внимание, что это работает с фактическими значениями пар значений - если у вас есть объекты различных видовэтот результат в указателях, мой алгоритм может потерпеть неудачу (я не проверял, поэтому я не уверен).Python повторно использует ту же ссылку на объект для «младших» целых чисел;то есть, если вы запускаете операторы a = 5 и b = 5 друг за другом, a и b будут указывать на один и тот же целочисленный объект.Однако, если вы установите их, скажем, 10 ^ 5, они не будут.Но я не знаю, где находится предел, поэтому я не уверен, относится ли это к вашему коду.

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