itertools
Mô-đun tích hợp của Python thực sự có một groupby
chức năng, nhưng để các phần tử được nhóm lại trước tiên phải được sắp xếp sao cho các phần tử được nhóm nằm liền kề trong danh sách:
from operator import itemgetter
sortkeyfn = itemgetter(1)
input = [('11013331', 'KAT'), ('9085267', 'NOT'), ('5238761', 'ETH'),
('5349618', 'ETH'), ('11788544', 'NOT'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('9843236', 'KAT'), ('5594916', 'ETH'), ('1550003', 'ETH')]
input.sort(key=sortkeyfn)
Bây giờ đầu vào trông giống như:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
trả về một chuỗi 2 bộ, có dạng (key, values_iterator)
. Những gì chúng tôi muốn là biến điều này thành một danh sách các phần trong đó 'type' là khóa và 'items' là danh sách các phần tử thứ 0 của các bộ giá trị được trả về bởi value_iterator. Như thế này:
from itertools import groupby
result = []
for key,valuesiter in groupby(input, key=sortkeyfn):
result.append(dict(type=key, items=list(v[0] for v in valuesiter)))
Bây giờ result
chứa chính tả mong muốn của bạn, như đã nêu trong câu hỏi của bạn.
Tuy nhiên, bạn có thể cân nhắc việc chỉ tạo một câu lệnh duy nhất trong số này, được khóa theo loại và mỗi giá trị chứa danh sách các giá trị. Trong biểu mẫu hiện tại của bạn, để tìm các giá trị cho một loại cụ thể, bạn sẽ phải lặp lại danh sách để tìm ra lệnh chứa khóa 'loại' phù hợp và sau đó lấy phần tử 'items' từ nó. Nếu bạn sử dụng một chính tả duy nhất thay vì danh sách gồm 1 mục, bạn có thể tìm thấy các mục cho một loại cụ thể bằng một lần tra cứu có khóa duy nhất trong chính tả. Sử dụng groupby
, điều này sẽ trông giống như:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
bây giờ chứa res
mệnh lệnh này (tương tự như lệnh mặc định trung gian trong câu trả lời của @ KennyTM):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(Nếu bạn muốn giảm điều này thành một lớp lót, bạn có thể:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
hoặc sử dụng biểu mẫu đọc hiểu chính tả mới:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]
trong đó phần tử cuối cùng của tuple là khóa và hai giá trị đầu tiên là giá trị. Kết quả sẽ như thế này: result = [{type: 'KAT', các mục: [( '11.013.331', đỏ), ( '9.085.267', xanh dương)]}]