подсчет строковых переключателей в списке с помощью groupby - PullRequest
1 голос
/ 19 марта 2019

У меня болит голова и словарь вот так:

{a: ['+','+','-','-','+','-','-','+'],
b: ['+','+','+','-','-','+','+','+','-'],
c: ['-','-','-','+','+','+']}

И я хочу знать, сколько раз меняется строка значений, что-то вроде этого:

a = 4
b = 3
c = 1

У меня естьпопытался использовать groupby из itertools, выполнив это:

for k, v in mydict.iteritems():
    print k + ' ' + str([len(list(g[1])) for g in groupby(list(v)) if g[0] =='+'])

Но я получаю только список, содержащий два значения (два строковых переключателя) .. Я попытался изменить символы «+» и «-» без успехакакие-нибудь рекомендации?

Ответы [ 2 ]

4 голосов
/ 19 марта 2019

Что-то, что вы могли бы сделать, это построить словарь с использованием словарного понимания и посчитать, сколько раз значения в каждой записи в словаре меняются:

d = {'a': ['+','+','-','-','+','-','-','+'], 'b': ['+','+','+','-','-','+','+','+','-'], 
     'c': ['-','-','-','+','+','+']}

s = {k : sum(1 for i,j in zip(d[k][1:], d[k][:-1]) if i != j) for k in d}
# {'a': 4, 'b': 3, 'c': 1}

Или, если вы предпочитаете, itertools.groupby:

{k : sum(1 for i in groupby(d[k]))-1 for k in d}
# {'a': 4, 'b': 3, 'c': 1}

Подробности

Чтобы обнаружить изменение элементов в каждом списке, вы можете сравнить его элементы с запаздывающей версией списка, что можно сделать, сжав два фрагмента списка, zip(d[k][1:], d[k][:-1]).

Например, для ключа a:

list(zip(d['a'][1:], d['a'][:-1]))
# [('+', '+'), ('-', '+'), ('-', '-'), ('+', '-'), ('-', '+'), ('-', '-'), ('+', '-')]

Теперь просто используйте выражение генератора и добавляйте 1 каждый раз, когда значения в кортеже различаются:

sum(1 for i,j in zip(d['a'][1:], d['a'][:-1]) if i != j)
# 4
2 голосов
/ 19 марта 2019

Вам не нужно фильтровать. Просто посчитайте группу:

mydict = {'a': ['+','+','-','-','+','-','-','+'],
'b': ['+','+','+','-','-','+','+','+','-'],
'c': ['-','-','-','+','+','+']}

for k,v in mydict.items():
  print(k + ' ' + str(len(list(itertools.groupby(list(v))))-1))
...