Сравните значения словаря для каждого ключа в том же словаре в Python

1

Update:

Привет. Мой вопрос в том, как я могу сравнить значения словаря для равенства. Дополнительная информация о моем словаре:

  • - номера сеансов
  • значения каждого ключа являются вложенными списками → f.e.

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

  • длина значений для каждого ключа arent одинакова, поэтому может быть, что номер сеанса 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: сохраните результат в списке f.e.   output = [[100,0], [23,2],...] или output = [(100,0), (23,2),...]

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

Спасибо, что помогли мне.

Обновление 2

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

Я предпочитаю решение Боаза Янива;) Мне также нравится использование коллекций. Counter()... неудачно, что я использую 2.6.4 (Counter работает в версии 2.7), возможно, я иногда меняю 2,7.

  • 1
    "Как я могу достичь этого результата?" Во-первых, напишите гораздо более четкое объяснение того, как человек будет проходить по словарю, сравнивая эти «пары значений» для получения выходных данных. Пожалуйста, напишите пошаговые инструкции, которым очень легко следовать. Не резюме, а пошагово («сначала сделай это, затем сделай это»). Когда вы это сделаете, мы можем показать, как написать пошаговые инструкции на Python после того, как вы написали их на английском языке. Пожалуйста, обновите вопрос с пошаговыми инструкциями для этого соответствия.
  • 1
    Вы, вероятно, найдете это более эффективным, если вы можете использовать список кортежей, например. [(100,0),(22,1),(23,2)]
Показать ещё 2 комментария
Теги:
dictionary

4 ответа

2
Лучший ответ

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

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
    умное использование операций над множествами здесь;)
  • 0
    Спасибо за ваше решение. Я предпочитаю этот, потому что у меня есть много пунктов в моем списке. И спасибо за подсказку, чтобы превратить его в кортежи вместо списков.
0
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

Вероятно, лучший и лучший способ сделать это, но я проделаю свой путь отсюда:

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, они не будут. Но я не знаю, где предел, поэтому я не уверен, относится ли это к вашему коду.

0
>>> 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]]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню