Как я могу использовать map для возврата измененного словаря на основе условий в одной строке кода?

#python #dictionary #lambda

#python #словарь #лямбда

Вопрос:

Здравствуйте, я должен написать функцию CustomOp(d) , которая принимает dict d и используется следующим образом:

 dict(map(CustomOp(d), d.items()))
 

Предполагается, что функция помогает изменять значения dicts на основе следующих условий:

  1. Если dict содержит только целые числа: удвойте каждое значение.
  2. Если он содержит только строки: переверните каждую строку.
  3. Если dict содержит другие типы или несколько разных типов: верните неизмененный dict

Кроме того, предполагается, что функция CustomOp(d) должна быть написана в одной строке кода (без учета заголовка obv)


Вот что мне удалось сделать до сих пор. Рекомендуется соблюдать осторожность!

 def UseOp(d):
    return dict(map(CustomOp(d), d.items()))
 
 def CustomOp(d):
    return lambda t:tuple([t[0],t[1]*2]) if all(type(v)==int for v in d.values()) else lambda t:tuple([t[0],t[1][::-1]]) if all(type(v)==str for v in d.values()) else lambda t:t
 

Это работает только тогда, когда Dict содержит только целые числа, иначе я получаю:

Ошибка типа: не удается преобразовать элемент последовательности обновления словаря # 0 в последовательность

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

Комментарии:

1. Вы можете писать CustomOp с несколькими строками кода? Я бы попробовал это сначала и только потом попытался сжать его до одной строки.

2. И можете ли вы выполнить 1. 2. и 3. по отдельности? Я бы тоже попробовал это сначала.

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

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

Ответ №1:

Попробуйте это, чтобы решить проблему:

     def CustomOp(d):
        return (lambda t:tuple([t[0],t[1]*2])) if all(type(v)==int for v in d.values()) else (lambda t:tuple([t[0],t[1][::-1]])) if all(type(v)==str for v in d.values()) else lambda t:t
 

Проблема в том, как вещи группируются между if else операторами — и lambda операторами.
Заключая ваши lambda операторы в круглые скобки, функция работает должным образом. Ваша логика была хорошей. Вы просто не учитывали приоритет / группировку операторов…

Комментарии:

1. Вау, спасибо, я бы никогда этого не понял, большое спасибо. Я хотел бы, чтобы мне понравился ваш пост, но у меня нет репутации, как кажется. У меня все еще остается вопрос, возможно ли это с менее чем 170 символами в этой чертовой строке

2. @NoCodeNoBlunder — Я думаю, вы все равно сможете выбрать ответ как лучший ответ.

3. Возможно, вам удастся достичь 170 символов, если вы объедините проверку типов с чем-то вроде all(введите (v) в (int, str) для …)

4. @NoCodeNoBlunder — Отлично. Если вы опубликуете 170 символов Q, я тоже могу вам помочь. Или, по крайней мере, попробуйте. 🙂