Сортировка списка списка кортежей по сумме первого поля в кортеже в Python - PullRequest
0 голосов
/ 22 декабря 2011

У меня есть внешний список, который содержит ежемесячное общее количество различных элементов в этом формате.Каждый месяц содержит одни и те же элементы.

big_list = [
  [
    (20, 'Item A', 'Jan'),
    (30, 'Item B', 'Jan'),
    (12, 'Item C', 'Jan'),
  ],
  [
    (22, 'Item A', 'Feb'),
    (34, 'Item B', 'Feb'),
    (15, 'Item C', 'Feb'),
  ],

  .... # until 'Dec'
]

И я хочу отсортировать этот список по общему количеству элементов за год. (сумма первого поля в кортеже определенного элемента в течение года) .Например, если Item C имеет наибольшее количество за два месяца, за которыми следуют Item A и Item B, конечный результат будет

[
  [
    (12, 'Item C', 'Jan'),
    (20, 'Item A', 'Jan'),
    (30, 'Item B', 'Jan'),
  ],
  [
    (15, 'Item C', 'Feb'),
    (22, 'Item A', 'Feb'),
    (34, 'Item B', 'Feb'),
  ],

  ... # until 'Dec'
]
# Item C = 12 + 15 = 27
# Item A = 20 + 22 = 42
# Item B = 30 + 34 = 64

Как мне этого добиться?Любая помощь или просвещение будет высоко ценится.

Ответы [ 4 ]

3 голосов
/ 22 декабря 2011
big_list = [
  [
    (20, 'Item A', 'Jan'),
    (30, 'Item B', 'Jan'),
    (12, 'Item C', 'Jan'),
  ],
  [
    (22, 'Item A', 'Feb'),
    (34, 'Item B', 'Feb'),
    (15, 'Item C', 'Feb'),
  ]]

s = {}
for l in big_list:
    for m in l:
        s[m[1]] = s.get(m[1], 0) + m[0]

дает нам s - суммы, которые мы хотим использовать для сортировки: {'Item A': 42, 'Item B': 64, 'Item C': 27}

И, наконец:

for l in big_list:
    l.sort(key=lambda x: s[x[1]])

изменяется big_list на:

[[(12, 'Item C', 'Jan'), (20, 'Item A', 'Jan'), (30, 'Item B', 'Jan')],
 [(15, 'Item C', 'Feb'), (22, 'Item A', 'Feb'), (34, 'Item B', 'Feb')]]

Это решение работает для списков в течение нескольких месяцев в любом порядке, а также, если какой-либо элемент не появляется в течение месяца.

1 голос
/ 22 декабря 2011

Если вам действительно нужны две строки:

for small_list in big_list:
  small_list.sort(key=lambda x: -sum([y[0] for l in big_list for y in l  if y[1] == x[1]]))

edit: или даже одна строка

[sorted(small_list, key=lambda x: -sum([y[0] for l in big_list for y in l  if y[1] == x[1]])) for small_list in big_list]
0 голосов
/ 22 декабря 2011

Мое предлагаемое решение:

[sublist.sort() for sublist in biglist]

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

0 голосов
/ 22 декабря 2011

@ Pankrat был близок:

for inner in big_list:
    inner.sort()

У вас есть список списков внутри, поэтому простой list.sort() не будет работать только на этом.Вы должны войти во внутренний список уровней, чтобы отсортировать его (который содержит кортежи).

К счастью, в вашем случае требуется только отсортировать первый элемент в кортежах;если бы вам пришлось отсортировать остальные, вам потребовалось бы что-то еще, например:

for inner in big_list:
    inner.sort(key = lambda x: x[i]) # i is the index location you want to sort on
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...