Вот мой (язык в щеке) ответ:
myDict = reduce(lambda d, t: (d.__setitem__(t[1], d.get(t[1], 0) + t[2]), d)[1], myTupleList, {})
Это уродливо и плохо, но вот как это работает.
Первый аргумент для уменьшения (потому что там неясно) это lambda d, t: (d.__setitem__(t[1], d.get(t[1], 0) + t[2]), d)[1]
. Я расскажу об этом позже, а сейчас я просто назову это joe
(не обижай никого по имени Джо). Функция сокращения в основном работает так:
joe(joe(joe({}, myTupleList[0]), myTupleList[1]), myTupleList[2])
И это для списка из трех элементов. Как вы можете видеть, он в основном использует свой первый аргумент для сортировки каждого результата в окончательный ответ. В этом случае окончательный ответ - это словарь, который вы хотели.
Теперь для самого joe
. Вот joe
как def
:
def joe(myDict, tupleItem):
myDict[tupleItem[1]] = myDict.get(tupleItem[1], 0) + tupleItem[2]
return myDict
К сожалению, никакие формы =
или return
не разрешены в Python lambda
, поэтому их нужно обойти. Я обошел проблему отсутствия =
, вызвав функцию dict
s __setitem__
напрямую. Я обошёл проблему отсутствия возврата, создав кортеж с возвращаемым значением __setitem__
и словарем, а затем вернул элемент кортежа, содержащий словарь. Я медленно изменю joe
, чтобы вы могли видеть, как я это сделал.
Сначала удалите =
:
def joe(myDict, tupleItem):
# Using __setitem__ to avoid using '='
myDict.__setitem__(tupleItem[1], myDict.get(tupleItem[1], 0) + tupleItem[2])
return myDict
Далее, приведите полное выражение к значению, которое мы хотим вернуть:
def joe(myDict, tupleItem):
return (myDict.__setitem__(tupleItem[1], myDict.get(tupleItem[1], 0) + tupleItem[2]),
myDict)[1]
Я много раз сталкивался с этим вариантом использования для reduce
и dict
в моем программировании на Python. На мой взгляд, dict
может использовать функцию-член reduceto(keyfunc, reduce_func, iterable, default_val=None)
. keyfunc
будет брать текущее значение из итерируемого и возвращать ключ. reduce_func
будет принимать существующее значение в словаре и значение из итерируемого и возвращать новое значение для словаря. default_val
будет тем, что было передано в reduce_func
, если в словаре отсутствует ключ. Возвращаемым значением должен быть сам словарь, чтобы вы могли делать такие вещи:
myDict = dict().reduceto(lambda t: t[1], lambda o, t: o + t, myTupleList, 0)