Python, работа со списками - PullRequest
5 голосов
/ 27 мая 2011

У меня есть такой код:

a = [[1, 1], [2, 1], [3, 0]]

Я хочу получить два списка, первый содержит элементы 'a', где a[][1] = 1, а второй - элементы, где a[][1] = 0.Итак,

first_list = [[1, 1], [2, 1]] 

second_list = [[3, 0]]. 

Я могу сделать это с пониманием двух списков:

first_list = [i for i in a if i[1] == 1]

second_list = [i for i in a if i[1] == 0]

Но, может быть, существует другой (более питонский или более короткий) способ сделать это?Спасибо за ваши ответы.

Ответы [ 6 ]

7 голосов
/ 27 мая 2011

Понимание списка очень питоническое и рекомендуемый способ сделать это.Ваш код в порядке.

3 голосов
/ 27 мая 2011

Если вы хотите, чтобы это было в одной строке, вы могли бы сделать что-то вроде

first_list, second_list = [i for i in a if i[1] == 1], [i for i in a if i[1] == 0]

Помните, что «явное лучше, чем неявное».

Ваш код в порядке

2 голосов
/ 27 мая 2011

Вы можете использовать sorted() и itertools.groupby(), чтобы сделать это, но я не знаю, что это будет квалифицироваться как Pythonic как таковое:

>>> dict((k, list(v)) for (k, v) in itertools.groupby(sorted(a, key=operator.itemgetter(1)), operator.itemgetter(1)))
{0: [[3, 0]], 1: [[1, 1], [2, 1]]}
0 голосов
/ 27 мая 2011

список понимания велики. Если вы хотите немного более простой код (но немного более длинный), просто используйте цикл for.

Еще одним вариантом будут фильтры и карты:

a = [[1, 1], [2, 1], [3, 0]]
g1=filter(lambda i: i[1]==1,a)
g1=map(lambda i: i[0],g1)
g2=filter(lambda i: i[1]==0,a)
g2=map(lambda i: i[0],g2)
print g1
print g2
0 голосов
/ 27 мая 2011

Если списки достаточно короткие, то хорошо подходят два их понимания: вам не стоит беспокоиться о производительности, пока весь код не работает и вы не знаете, что он слишком медленный.

Если ваши списки длинныеили код часто запускается и , вы продемонстрировали, что это узкое место, тогда все, что вам нужно сделать, - это переключиться со списочных представлений на цикл for:

first_list, second_list = [], []
for element in a:
    if element[1] == 1:
        first_list.append(element)
    else:
        second_list.append(element)

, что и ясно, илегко распространяется на большее количество случаев.

0 голосов
/ 27 мая 2011

как насчет этого,

In [1]: a = [[1, 1], [2, 1], [3, 0]]

In [2]: first_list = []

In [3]: second_list = []

In [4]: [first_list.append(i) if i[1] == 1 else second_list.append(i) for i in a]
Out[4]: [None, None, None]

In [5]: first_list, second_list
Out[5]: ([[1, 1], [2, 1]], [[3, 0]])

вместо двух подсписков, я предпочитаю dict (или defaultdict, OrderedDict, Counter и т. Д.)

In [6]: from collections import defaultdict

In [7]: d = defaultdict(list)

In [8]: [d[i[1]].append(i) for i in a]
Out[8]: [None, None, None]

In [9]: d
Out[9]: {0: [[3, 0]], 1: [[1, 1], [2, 1]]}
...