Как сгруппировать список по значениям? - PullRequest
1 голос
/ 15 июня 2019

Допустим, у меня есть такой список:

[['John', 1], ['Fred', 1], ['Carolyn', 1], ['Kenneth', 3], ['Ronald', 3], ['Dorothy', 2], ['Joyce', 2], ['Julia', 3], ['Deborah', 1], ['Jonathan', 2], ['Aaron', 2], ['Marie', 1], ['Adam', 2], ['Kevin', 2], ['Alice', 2], ['Jerry', 1], ['Kimberly', 1], ['Lawrence', 1], ['Louis', 2], ['Anthony', 1], ['Carolyn', 3], ['Edward', 2], ['Samuel', 3], ['Rachel', 1], ['Kathleen', 1], ['Fred', 3], ['Fred', 3], ['Gerald', 2], ['Donna', 2], ['Keith', 3], ['Matthew', 3], ['Stephanie', 1]]

Как я могу получить этот вывод:

John Dorothy Kenneth
Fred Joyce Ronald
Carolyn Jonathan Julia
Deborah Aaron Carolyn
Marie Adam Samuel
Jerry Kevin Fred
Kimberly Alice Fred
Lawrence Louis Keith
Anthony Edward Matthew

То, что я пытаюсь сделать, это сгруппировать в группы по 3 элемента. Если группа не состоит из 3 имен, она не будет отображаться.

Другой пример:

Ввод:

[['Heather', 2], ['Evelyn', 1], ['Norma', 1], ['Evelyn', 3], ['Harry', 3], ['Sean', 1], ['Anna', 1], ['Jerry', 3], ['Anna', 3], ['Julia', 1], ['Dorothy', 2]]

Ожидаемый результат:

Evelyn Heather Evelyn
Norma Dorothy Harry

До сих пор мне удавалось группировать их имена в подсписки по каждому номеру (1, 2, 3).

r = [[] for i in range(3)]
for i in l:
    if i[1] == 1:
        r[0].append(i[0])
    elif i[1] == 2:
        r[1].append(i[0])
    elif i[1] == 3:
        r[2].append(i[0])
print r

r = [['John', 'Fred', 'Carolyn', 'Deborah', 'Marie', 'Jerry', 'Kimberly', 'Lawrence', 'Anthony', 'Rachel', 'Kathleen', 'Stephanie'], ['Dorothy', 'Joyce', 'Jonathan', 'Aaron', 'Adam', 'Kevin', 'Alice', 'Louis', 'Edward', 'Gerald', 'Donna'], ['Kenneth', 'Ronald', 'Julia', 'Carolyn', 'Samuel', 'Fred', 'Fred', 'Keith', 'Matthew']]

Ответы [ 7 ]

1 голос
/ 15 июня 2019

Вы можете сделать это довольно кратко с комбинацией zip и itertools.groupby.Сначала отсортируйте список по номеру, затем сгруппируйте и заархивируйте.Если вы хотите строки, вы можете присоединиться:

from operator import itemgetter
from itertools import groupby

l = [['John', 1], ['Fred', 1], ['Carolyn', 1], ['Kenneth', 3], ['Ronald', 3], ['Dorothy', 2], ['Joyce', 2], ['Julia', 3], ['Deborah', 1], ['Jonathan', 2], ['Aaron', 2], ['Marie', 1], ['Adam', 2], ['Kevin', 2], ['Alice', 2], ['Jerry', 1], ['Kimberly', 1], ['Lawrence', 1], ['Louis', 2], ['Anthony', 1], ['Carolyn', 3], ['Edward', 2], ['Samuel', 3], ['Rachel', 1], ['Kathleen', 1], ['Fred', 3], ['Fred', 3], ['Gerald', 2], ['Donna', 2], ['Keith', 3], ['Matthew', 3], ['Stephanie', 1]]

l.sort(key = itemgetter(1))
groups = zip(*([name for name, g in n] for k, n in groupby(l, itemgetter(1))))

[" ".join(names) for names in groups]

вывод:

['John Dorothy Kenneth',
 'Fred Joyce Ronald',
 'Carolyn Jonathan Julia',
 'Deborah Aaron Carolyn',
 'Marie Adam Samuel',
 'Jerry Kevin Fred',
 'Kimberly Alice Fred',
 'Lawrence Louis Keith',
 'Anthony Edward Matthew']
1 голос
/ 15 июня 2019

как насчет:

l = [['Heather', 2], ['Evelyn', 1], ['Norma', 1], ['Evelyn', 3], ['Harry', 3], ['Sean', 1], ['Anna', 1], ['Jerry', 3], ['Anna', 3], ['Julia', 1], ['Dorothy', 2]]
from itertools import groupby
def keyfunc(arr) :
   return arr[1]

l = sorted(l, key=keyfunc)
s =[[*x,] for  i,x in groupby(data , keyfunc)]
combinations = [*zip(*s),]

и затем вы можете просто распечатать элементы, выполнив:

for l in combinations :
   print(' '.join([x[0] for x in l]))

распечатывает:

John Dorothy Kenneth
Fred Joyce Ronald
Carolyn Jonathan Julia
Deborah Aaron Carolyn
Marie Adam Samuel
Jerry Kevin Fred
Kimberly Alice Fred
Lawrence Louis Keith
Anthony Edward Matthew
1 голос
/ 15 июня 2019

Вот подход, подобный этому вопросу:

l1 = [['John', 1], ['Fred', 1], ['Carolyn', 1], ['Kenneth', 3], ['Ronald', 3], ['Dorothy', 2], ['Joyce', 2], ['Julia', 3], ['Deborah', 1], ['Jonathan', 2], ['Aaron', 2], ['Marie', 1], ['Adam', 2], ['Kevin', 2], ['Alice', 2], ['Jerry', 1], ['Kimberly', 1], ['Lawrence', 1], ['Louis', 2], ['Anthony', 1], ['Carolyn', 3], ['Edward', 2], ['Samuel', 3], ['Rachel', 1], ['Kathleen', 1], ['Fred', 3], ['Fred', 3], ['Gerald', 2], ['Donna', 2], ['Keith', 3], ['Matthew', 3], ['Stephanie', 1]]
l2 = [['Heather', 2], ['Evelyn', 1], ['Norma', 1], ['Evelyn', 3], ['Harry', 3], ['Sean', 1], ['Anna', 1], ['Jerry', 3], ['Anna', 3], ['Julia', 1], ['Dorothy', 2]]

def get_exp(l):
    v = set(map(lambda x:x[1], l))
    nl = [[y[0] for y in l if y[1]==x] for x in v]
    return '\n'.join(list(map(' '.join, zip(*nl))))
output_l1 = get_exp(l1)
output_l2 = get_exp(l2)

output_l1 :

John Dorothy Kenneth
Fred Joyce Ronald
Carolyn Jonathan Julia
Deborah Aaron Carolyn
Marie Adam Samuel
Jerry Kevin Fred
Kimberly Alice Fred
Lawrence Louis Keith
Anthony Edward Matthew

output_l2 :

Evelyn Heather Evelyn
Norma Dorothy Harry
0 голосов
/ 16 июня 2019

Использование numpy - это еще один способ сделать это:

import math
import numpy as np

data = [['John', 1], ['Fred', 1], ['Carolyn', 1], ['Kenneth', 3], ['Ronald', 3], ['Dorothy', 2], ['Joyce', 2], ['Julia', 3], ['Deborah', 1], ['Jonathan', 2], ['Aaron', 2], ['Marie', 1], ['Adam', 2], ['Kevin', 2], ['Alice', 2], ['Jerry', 1], ['Kimberly', 1], ['Lawrence', 1], ['Louis', 2], ['Anthony', 1], ['Carolyn', 3], ['Edward', 2], ['Samuel', 3], ['Rachel', 1], ['Kathleen', 1], ['Fred', 3], ['Fred', 3], ['Gerald', 2], ['Donna', 2], ['Keith', 3], ['Matthew', 3], ['Stephanie', 1]]

array = np.array([x[0] for x in data])
array = np.resize(array,(3,math.ceil(len(array)/3))).T

[" ".join(x) for x in array]

Выход:

['John Marie Samuel',
 'Fred Adam Rachel',
 'Carolyn Kevin Kathleen',
 'Kenneth Alice Fred',
 'Ronald Jerry Fred',
 'Dorothy Kimberly Gerald',
 'Joyce Lawrence Donna',
 'Julia Louis Keith',
 'Deborah Anthony Matthew',
 'Jonathan Carolyn Stephanie',
 'Aaron Edward John']
0 голосов
/ 16 июня 2019

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

def gum(l):
    g = {}
    for n, k in l:
        g.setdefault(k, []).append(n)
    return zip(*g.values())

l1 = [['John', 1], ['Fred', 1], ['Carolyn', 1],
      ['Kenneth', 3], ['Ronald', 3], ['Dorothy', 2],
      ['Joyce', 2], ['Julia', 3], ['Deborah', 1],
      ['Jonathan', 2], ['Aaron', 2], ['Marie', 1],
      ['Adam', 2], ['Kevin', 2], ['Alice', 2],
      ['Jerry', 1], ['Kimberly', 1], ['Lawrence', 1],
      ['Louis', 2], ['Anthony', 1], ['Carolyn', 3],
      ['Edward', 2], ['Samuel', 3], ['Rachel', 1],
      ['Kathleen', 1], ['Fred', 3], ['Fred', 3],
      ['Gerald', 2], ['Donna', 2], ['Keith', 3],
      ['Matthew', 3], ['Stephanie', 1]]

l2 = [['Heather', 2], ['Evelyn', 1], ['Norma', 1],
      ['Evelyn', 3], ['Harry', 3], ['Sean', 1],
      ['Anna', 1], ['Jerry', 3], ['Anna', 3],
      ['Julia', 1], ['Dorothy', 2]]

print '\n\n'.join('\n'.join(' '.join(n) for n in l) for l in [gum(l1), gum(l2)])

Вывод:

John Dorothy Kenneth
Fred Joyce Ronald
Carolyn Jonathan Julia
Deborah Aaron Carolyn
Marie Adam Samuel
Jerry Kevin Fred
Kimberly Alice Fred
Lawrence Louis Keith
Anthony Edward Matthew

Evelyn Heather Evelyn
Norma Dorothy Harry
0 голосов
/ 15 июня 2019
lst1 = [['John', 1], ['Fred', 1], ['Carolyn', 1], ['Kenneth', 3], ['Ronald', 3], ['Dorothy', 2], ['Joyce', 2], ['Julia', 3], ['Deborah', 1], ['Jonathan', 2], ['Aaron', 2], ['Marie', 1], ['Adam', 2], ['Kevin', 2], ['Alice', 2], ['Jerry', 1], ['Kimberly', 1], ['Lawrence', 1], ['Louis', 2], ['Anthony', 1], ['Carolyn', 3], ['Edward', 2], ['Samuel', 3], ['Rachel', 1], ['Kathleen', 1], ['Fred', 3], ['Fred', 3], ['Gerald', 2], ['Donna', 2], ['Keith', 3], ['Matthew', 3], ['Stephanie', 1]]
lst2 = [['Heather', 2], ['Evelyn', 1], ['Norma', 1], ['Evelyn', 3], ['Harry', 3], ['Sean', 1], ['Anna', 1], ['Jerry', 3], ['Anna', 3], ['Julia', 1], ['Dorothy', 2]]

from itertools import groupby

def my_print(lst):
    d = {v: list(g) for v, g in groupby(sorted(lst, key=lambda k: k[-1]), lambda v: v[-1])}
    while True:
        try:
            i1 = d[1].pop(0)
            i2 = d[2].pop(0)
            i3 = d[3].pop(0)
            print('{} {} {}'.format(i1[0], i2[0], i3[0]))
        except IndexError:
            break

my_print(lst1)
print('*' * 80)
my_print(lst2)

Печать:

John Dorothy Kenneth
Fred Joyce Ronald
Carolyn Jonathan Julia
Deborah Aaron Carolyn
Marie Adam Samuel
Jerry Kevin Fred
Kimberly Alice Fred
Lawrence Louis Keith
Anthony Edward Matthew
********************************************************************************
Evelyn Heather Evelyn
Norma Dorothy Harry
0 голосов
/ 15 июня 2019

Я думаю, что самый простой ответ - использовать словарь для сбора результатов по номеру, который у вас есть (это будет ключ словаря).Затем вы можете просмотреть результаты в словаре по длине:

In [7]: from collections import defaultdict                                     

In [8]: results = defaultdict(list)                                             

In [9]: name_list = [['bob', 1], ['cindy', 1], ['ted', 2]]                      

In [10]: for (value, key) in name_list: 
    ...:     results[key].append(value) 
    ...:                                                                        

In [11]: results                                                                
Out[11]: defaultdict(list, {1: ['bob', 'cindy'], 2: ['ted']})



In [13]: for key in results: 
    ...:     if len(results.get(key)) == 2: 
    ...:         print( 'found a result of length 2: ', results.get(key)) 
    ...:                                                                        
found a result of length 2:  ['bob', 'cindy']
...