исправленный в Python массив динамических строк - PullRequest
0 голосов
/ 20 марта 2019

Я хотел бы итеративно заполнить массив фиксированного размера, где каждый элемент представляет собой список строк. Например, давайте рассмотрим следующий список строк:

arr = ['A1', 'C3', 'B2', 'A2', 'C1', 'A3', 'B1', 'C2', 'A4']

Я хочу получить следующий массив из 3 элементов (упорядочение не требуется):

res = [['A1', 'A2', 'A3', 'A4'],
       ['B2', 'B1'],
       ['C3', 'C1', 'C2']]

У меня есть следующий фрагмент кода:

arr = ['A1', 'C3', 'B2', 'A2', 'C1', 'A3', 'B1', 'C2', 'A4']
res = [[]] * 3
for i in range(len(arr)):
    # Calculate index corresponding to A, B or C
    j = ord(arr[i][0])-65
    # Extend corresponding string list
    res[j].extend([arr[i]])

for i in range(len(res)):
    print(res[i])

Но я получаю такой результат:

['A1', 'C3', 'B2', 'A2', 'C1', 'A3', 'B1', 'C2', 'A4']
['A1', 'C3', 'B2', 'A2', 'C1', 'A3', 'B1', 'C2', 'A4']
['A1', 'C3', 'B2', 'A2', 'C1', 'A3', 'B1', 'C2', 'A4']

Где я не прав, пожалуйста? Спасибо за вашу помощь!

Ответы [ 3 ]

2 голосов
/ 20 марта 2019

Вы можете использовать itertools.groupby и группировать элементы в списке (отсортированные) по первому элементу.Вы можете использовать operator.itemgetter для эффективного извлечения первой подстроки в каждой строке:

from itertools import groupby
from operator import itemgetter

[list(v) for k,v in groupby(sorted(arr), key=itemgetter(0))]
# [['A1', 'A2', 'A3', 'A4'], ['B1', 'B2'], ['C1', 'C2', 'C3']]
0 голосов
/ 20 марта 2019

Проблема связана со следующим: res = [[]] * 3 создаст три списка, но все три являются одинаковым объектом. Поэтому, когда вы добавляете или расширяете один из них, он будет добавлен к «всем» (в конце концов, это все один и тот же объект).

Вы можете легко проверить это, заменив его следующим: res = [[],[],[]] который затем даст вам ожидаемый ответ.

Рассмотрим эти фрагменты:

res = [[]]*2
res[0].append(1)
print(res)

Out:
[[1], [1]]

В то время как

res = [[],[]]
res[0].append(1)
print(res)

Out:
[[1], []]

В качестве альтернативы вы можете создать вложенный список следующим образом: res = [[] for i in range(3)]

0 голосов
/ 20 марта 2019

Вы можете использовать понимание списка:

[[k for k in arr if k[0]==m] for m in sorted(set([i[0] for i in arr]))]

ВЫХОД :

[['A1', 'A2', 'A3', 'A4'], ['B2', 'B1'], ['C3', 'C1', 'C2']]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...