Как разделить один список на два через понимание списка или иным образом - PullRequest
1 голос
/ 22 января 2010

Если есть список элементов словаря, например:

L = [{"a":1, "b":0}, {"a":3, "b":1}...]

Я хотел бы разделить эти записи на основе значения "b", 0 или 1.

A(b=0) = [{"a":1, "b":1}, ....]
B(b=1) = [{"a":3, "b":2}, .....]

Мне удобно использовать простые списки, и я в настоящее время перебираю список L два раза.

A = [d for d in L if d["b"] == 0]
B = [d for d in L if d["b"] != 0]

Очевидно, что это не самый эффективный способ.

Предложение else, по-видимому, недоступно в функциях понимания списка.

Могу ли я делать то, что я хочу, через понимание списка?

Есть ли лучший способ сделать это?

Я ищу хороший баланс между удобочитаемостью и эффективностью, склоняясь к удобочитаемости.

Спасибо!

обновление: спасибо всем за комментарии и идеи! мне проще всего читать Томаса. но я тоже посмотрю на предложение Алекса. я не нашел никаких ссылок на модуль коллекций.

Ответы [ 2 ]

5 голосов
/ 22 января 2010

Не используйте понимание списка. Понимание списка - это когда вы хотите получить единый список результатов. Вы, очевидно, не :) Используйте регулярный цикл for:

A = []
B = []
for item in L:
    if item['b'] == 0:
        target = A
    else:
        target = B
    target.append(item)

Вы можете сократить фрагмент, скажем, (A, B)[item['b'] != 0].append(item), но зачем?

3 голосов
/ 22 января 2010

Если значение b может быть только 0 или 1, простое решение @ Thomas, вероятно, будет лучшим. Для более общего случая (в котором вы хотите различить несколько возможных значений b) ваш пример «ожидаемых результатов», по-видимому, полностью отделен от текста вашего вопроса и противоречит ему, поэтому далеко не очевидно, действительно ли вам нужно некоторая общность; -):

from collections import defaultdict

separated = defaultdict(list)
for x in L:
  separated[x['b']].append(x)

Когда этот код выполняется, separated заканчивается dict (фактически экземпляром collections.defaultdict, dict подклассом), ключи которого - все значения для b, которые фактически происходят в dict с. в списке L, соответствующие значения являются разделенными подсписками. Так, например, если b принимает только значения 0 и 1, separated[0] будет тем, что (в тексте вашего вопроса в отличие от примера) вы хотите использовать в качестве списка A и separated[1] что вы хотите, как список B.

...