2013-08-15 5 views
0

У меня есть список словарей. Можно предположить, что в каждом списке есть словари того же формата. Давайте назовем этот формат:Разбивка списка по частям по

dict_sample={'a':0,'b':1} 

Давайте также сказать, что a является случайным числом, в то время как б может быть один из нескольких чисел (или строк, по этому вопросу). Я хочу отсортировать все значения a на b. Например, если у меня есть список:

a b 
54 1 
25 0 
53 1 
532 2 
132 0 

list=[{'a':54,'b':1},{'a':25,'b':0},{'a':53,'b':1},{'a':532,'b':2},{'a':132,'b':0}] 

Я хотел бы разбить его на 3 списка. Списки будут включать (Order не важно)

0 list-> [25,132] 
1 list-> [54,53] 
2 list-> [532] 

Я знаю, что могу побить все a «S из списка следующим образом, но я не могу вполне понять, элегантное решение для сортировки a» S по b «s. Какие-либо предложения? Мой код до сих пор выглядит следующим образом:

[row['a'] for row in list] 

То, что я хотел бы что-то вроде этого:

index=0  #This could be looped through, or just chosen for one specific value 
[row['a'] if row['b']==index for row in list] 
+0

Почему бы вам не просто '(a, b)' кортежи? – user2357112

+0

Мои настоящие словари довольно длинны, и я не хочу вспоминать, что такое схема индексирования.Я бы просто дал каждому значению имя. – PearsonArtPhoto

+0

'(a, b)' ['namedtuple'] (http://docs.python.org/2/library/collections.html#collections.namedtuple) s может быть тогда полезен. – user2357112

ответ

1

Если вы уже знали все значения b, это было бы тривиально. Вам нужен список для каждого значения b, где каждый из них имеет все значения a в каждом словаре с этим значением b. Вы можете перевести, что практически сразу с английского языка к пониманию:

[[d['a'] for d in lst if d['b']==b] for b in bs] 

Вы не имеете b значения, но вы можете получить их просто делать еще один проход:

bs = (d['b'] for d in lst) 

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

bs = sorted(set(d['b'] for d in lst)) 

и это все есть на него. Объединение:

>>> lst=[{'a':54,'b':1},{'a':25,'b':0},{'a':53,'b':1},{'a':532,'b':2},{'a':132,'b':0}] 
>>> bs = sorted(set(d['b'] for d in lst)) 
>>> [[d['a'] for d in lst if d['b']==b] for b in bs] 
[[25, 132], [54, 53], [532]] 
+0

Все, что мне нужно было сделать, это поставить 'if' после цикла' for'. Вздох. Спасибо, что указали на ошибку моего пути! – PearsonArtPhoto

+0

@PearsonArtPhoto: Ах, я понимаю, где вы поступили не так. Когда вы впервые смотрите на понимание нескольких предложений, многие люди ожидают, что он будет действовать в порядке наименьшего изящества - самое внутреннее выражение слева, поэтому оно должно быть гнездоем справа налево, правильно? Но нет, самое внутреннее выражение является особенным и на первом месте, но кластеры гнездятся слева направо. (Это очень сложно объяснить в комментарии, но я подозреваю, что у вас уже есть основная идея, и я могу прочитать справочные документы, если вам нужны подробности, надеюсь ...) – abarnert

+0

Это, безусловно, имеет больше смысла, чем это было. Вам придется продолжать пытаться. Благодаря! – PearsonArtPhoto

1

Возможное (компактный) решение:

output= { ok: [ ie['a'] for ie in list if ie['b'] == ok ] for ok in { e['b'] for e in list } } 

Обратите внимание, что является множество понятий (относительно новая особенность языка). Примерно эквивалентен set([ e['b'] for e in list ])

Я протестировал его на CPython 3.3.2, и он выражает ожидаемый результат, за исключением того, что в словаре. ИМХО, списки более полезны в словаре, чем где-нибудь еще, но соблюдать вопрос:

list_0= output[0] 
list_1= output[1] 
list_2= output[2] 
3
from collections import defaultdict 

data=[{'a':54,'b':1},{'a':25,'b':0},{'a':53,'b':1},{'a':532,'b':2},{'a':132,'b':0}] 

output = defaultdict(list) 

for d in data: 
    output[d['b']].append(d['a']) 

output = sorted((k, v) for k, v in output.items()) 

print output 

ВЫВОД:

[(0, [25, 132]), (1, [54, 53]), (2, [532])] 
+0

Это лучше, чем у меня. – erewok

+0

Это тоже неплохо! – PearsonArtPhoto

+0

Это дает вам (по умолчанию) dict, а не список, что, конечно же, означает, что он не отсортирован по порядку ... но вы всегда можете сортировать значения dict, используя соответствующие ключи в качестве ключа сортировки, в еще одной строке. – abarnert

0
mylist=[{'a':54,'b':1},{'a':25,'b':0},{'a':53,'b':1},{'a':532,'b':2},{'a':132,'b':0}] 

>>> zerolist, onelist, twolist = [], [], [] 
>>> for x in mylist: 

     if 0 in x.values(): 
      zerolist.append(x['a']) 
     elif 1 in x.values(): 
       onelist.append(x['a']) 
     elif 2 in x.values(): 
       onelist.append(x['a']) 
>>> >>> zerolist 
[25, 132]