для более подробного объяснения.

я есть массив, и я хочу подсчитать вхождение каждого элемента в массиве.

Мне удалось использовать функцию карты, чтобы создать список кортежей.

def mapper(a):
    return (a, 1)

r = list(map(lambda a: mapper(a), arr));

//output example: 
//(11817685, 1), (2014036792, 1), (2014047115, 1), (11817685, 1)

Я ожидаю, что функция сокращения может помочь мне сгруппировать счетчики по первому числу (id) в каждом кортеже. Например:

(11817685, 2), (2014036792, 1), (2014047115, 1)

Я пытался

cnt = reduce(lambda a, b: a + b, r);

и некоторые другие способы, но все они не справляются.

НОТА Спасибо за все советы по другим способам решения проблем, но я просто изучаю Python и рассказываю, как реализовать сокращение карты, и я значительно упростил свою реальную бизнес-задачу, чтобы ее было легко понять, поэтому, пожалуйста, любезно покажи мне правильный способ сделать карту-уменьшить.

 Lee13 дек. 2017 г., 03:48
Просто посредник.
 Lee13 дек. 2017 г., 03:47
Спасибо за комментарий. Да, я могу просто пройти прямо в маппере, экспериментировал с чем-то другим. Добавили мой ожидаемый результат.
 internet_user13 дек. 2017 г., 03:48
Тебе нужноr или это просто посредник?
 internet_user13 дек. 2017 г., 03:43
lambda a: mapper(a)? Почему бы просто не пройтиmapper? Также: каков ваш ожидаемый результат?
 ShadowRanger13 дек. 2017 г., 03:52
ниreduce ниmap действительно помогает вам здесь. Это такая задача, почемуcollections.Counter существует (и для более специализированных случаев, когда входные данные уже отсортированы,itertools.groupby). Стратегии Map / Reduce предназначены для случаев, когда у вас есть много картографов, параллельно питающих много редукторов параллельно; слепое применение одного и того же шаблона к чисто однопоточному коду бесполезно (в случаях Map / Reduce это также расточительно, вы просто рассчитываете на абсурдные уровни параллелизма, чтобы компенсировать накладные расходы).

Ответы на вопрос(4)

оторую логику и делать это без какого-либо модуля:

track={}
if intr not in track:
    track[intr]=1
else:
    track[intr]+=1

Пример кода:

Для этих типов задач списка есть шаблон:

Итак, предположим, у вас есть список:

a=[(2006,1),(2007,4),(2008,9),(2006,5)]

И вы хотите преобразовать это в dict в качестве первого элемента кортежа в качестве ключа и второго элемента кортежа. что-то вроде :

{2008: [9], 2006: [5], 2007: [4]}

Но есть ловушка, которую вы также хотите, чтобы эти ключи имели разные значения, но ключи были такими же, как ключи (2006,1) и (2006,5), но значения разные. Вы хотите, чтобы эти значения добавлялись только с одним ключом, поэтому ожидаемый результат:

{2008: [9], 2006: [1, 5], 2007: [4]}

для этого типа проблемы мы делаем что-то вроде этого:

сначала создайте новый dict, затем мы следуем этой схеме:

if item[0] not in new_dict:
    new_dict[item[0]]=[item[1]]
else:
    new_dict[item[0]].append(item[1])

Поэтому мы сначала проверяем, находится ли ключ в новом dict, и если он уже есть, затем добавляем значение дубликата ключа к его значению:

полный код:

a=[(2006,1),(2007,4),(2008,9),(2006,5)]

new_dict={}

for item in a:
    if item[0] not in new_dict:
        new_dict[item[0]]=[item[1]]
    else:
        new_dict[item[0]].append(item[1])

print(new_dict)

выход:

{2008: [9], 2006: [1, 5], 2007: [4]}

cnt, затемdict вероятно, будет лучше, чемlist изtupleздесь (если вам нужен этот формат, просто используйтеdict.items).

collections Модуль имеет полезную структуру данных для этого,defaultdict.

from collections import defaultdict
cnt = defaultdict(int) # create a default dict where the default value is
                       # the result of calling int
for key in arr:
  cnt[key] += 1 # if key is not in cnt, it will put in the default

# cnt_list = list(cnt.items())

мой ответ вдругой вопросЯ запомнил этот пост и подумал, что было бы полезно написать подобный ответ здесь.

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

arr = [11817685, 2014036792, 2014047115, 11817685]

def mapper(a):
    return (a, 1)

def reducer(x, y):
    if isinstance(x, dict):
        ykey, yval = y
        if ykey not in x:
            x[ykey] = yval
        else:
            x[ykey] += yval
        return x
    else:
        xkey, xval = x
        ykey, yval = y
        a = {xkey: xval}
        if ykey in a:
            a[ykey] += yval
        else:
            a[ykey] = yval
        return a

mapred = reduce(reducer, map(mapper, arr))

print mapred.items()

Какие отпечатки:

[(2014036792, 1), (2014047115, 1), (11817685, 2)]

Пожалуйста, смотритесвязанный ответ для более подробного объяснения.

Вы могли бы использоватьCounter:

from collections import Counter
arr = [11817685, 2014036792, 2014047115, 11817685]
counter = Counter(arr)
print zip(counter.keys(), counter.values())

РЕДАКТИРОВАТЬ:

Как указано @ShadowRangerCounter имеетitems() метод:

from collections import Counter
arr = [11817685, 2014036792, 2014047115, 11817685]
print Counter(arr).items()
 ShadowRanger13 дек. 2017 г., 03:55
Почемуzip keys а такжеvalues? Там естьitems метод, который делает это напрямую:print counter.items()и специальный методmost_common, который показывает вам результаты по порядку по частоте (с необязательным ограничением количества результатов), например,print counter.most_common().

Ваш ответ на вопрос