Giả sử số lượng các phím, và các giá trị cho mỗi khoá, đều tùy ý và không xác định trước, nó đơn giản nhất để có được kết quả với các vòng lặp, tất nhiên:
itit = thedict.iteritems()
k, vs = next(itit)
result = [{k: v} for v in vs]
for k, vs in itit:
for d, v in itertools.izip(result, vs):
d[k] = v
Nó có thể bị sụp đổ, nhưng tôi không chắc chắn về hiệu quả của việc thực hiện (nếu cấu trúc dữ liệu có liên quan quá lớn để đảm bảo tối ưu hóa hiệu suất, xây dựng thêm bất kỳ cấu trúc phụ nào trong bộ nhớ tốn kém - cách tiếp cận đơn giản này của tôi là đặc biệt cẩn thận để tránh bất kỳ cấu trúc trung gian nào như vậy).
Chỉnh sửa: một lựa chọn khác, đặc biệt thú vị nếu cấu trúc dữ liệu tổng thể rất lớn nhưng trong một số trường hợp sử dụng, bạn chỉ cần "bit và miếng" của cấu trúc "được chuyển đổi", là xây dựng một lớp cung cấp giao diện bạn yêu cầu, nhưng thay vào đó là "trên bay", thay vì trong một "cú đánh lớn", "một lần và cho tất cả" chuyển đổi (điều này có thể đặc biệt hữu ích nếu cấu trúc ban đầu có thể thay đổi và cấu trúc được chuyển đổi cần phản ánh trạng thái hiện tại của bản gốc, v.v.).
Tất nhiên, với mục đích như vậy, rất hữu ích để xác định chính xác những tính năng của "danh sách từ điển" mà mã hạ lưu của bạn sẽ sử dụng. Giả sử ví dụ rằng tất cả những gì bạn cần là lập chỉ mục "chỉ đọc" (không thay đổi, lặp lại, cắt, sắp xếp, ...): X[x]
phải trả về một từ điển trong đó mỗi khóa k ánh xạ tới một giá trị như vậy (caling O
từ điển ban đầu của danh sách) X[x][k] is O[k][x]
. Sau đó:
class Wrap1(object):
def __init__(self, O):
self.O = O
def __getitem__(self, x):
return dict((k, vs[x]) for k, vs in self.O.iteritems())
Nếu bạn không thực sự cần cấu trúc bọc để theo dõi những thay đổi với một bản gốc, sau đó __getitem__
rất có thể cũng "cache" dict nó trở về:
class Wrap2(object):
def __init__(self, O):
self.O = O
self.cache = {}
def __getitem__(self, x):
r = self.cache.get(x)
if r is None:
r = self.cache[x] = dict((k, vs[x]) for k, vs in self.O.iteritems())
return r
Lưu ý rằng cách tiếp cận này có thể kết thúc với một số bản sao trong bộ nhớ cache, ví dụ: nếu danh sách của O
có 7 mục, bộ nhớ cache tại x==6
và x==-1
có thể kết thúc với hai chữ cái bằng nhau; nếu đó là một vấn đề bạn có thể, ví dụ, bình thường hóa tiêu cực x
s trong __getitem__
bằng cách thêm len(self.O)
cho họ trước khi tiếp tục.
Nếu bạn cũng cần lặp lại, cũng như chỉ mục đơn giản này, điều đó không quá khó: chỉ cần thêm phương thức __iter__
, dễ dàng triển khai, ví dụ: như một máy phát điện đơn giản ...:
def __iter__(self, x):
for i in xrange(len(self.O)):
yield self[i]
Và vân vân, từng bước, nếu và khi bạn cần ngày càng nhiều các chức năng của một danh sách (lúc tồi tệ nhất, một khi bạn đã thực hiện điều này __iter__
, bạn có thể xây dựng self.L = list(self)
- quay trở lại các "vụ nổ lớn" cách tiếp cận - và, đối với bất kỳ yêu cầu nào khác, hãy gửi đến self.L
... nhưng bạn sẽ phải tạo một metaclass đặc biệt nếu bạn muốn sử dụng phương pháp đó cho các phương pháp đặc biệt hoặc sử dụng một số mẹo phụ như self.__class__ = list; self[:] = self.L
đã theo dõi theo thích hợp del
s ;-).
Bạn có thể muốn làm rõ câu hỏi của bạn một chút ... Tôi đã mất một thời gian để hiểu những gì bạn muốn từ ví dụ của bạn: chuyển đổi một bản đồ với hai phím (key1 , key2) mỗi danh sách có các giá trị (có cùng độ dài, nhưng khác nhau) cho một danh sách các cặp vợ chồng và trong cặp vợ chồng tại vị trí i, key1 và key2 được đặt thành phần tử thứ i của danh sách tương ứng. Là nó? –
Tại sao lại có niềm đam mê khi làm việc đó mà không có vòng lặp? Đó là một hạn chế ngu ngốc. – jcdyer
nó không phải là phải, tôi đã viết "tốt hơn". Suy nghĩ có thể có một cách nhanh chóng để làm điều này (một số chức năng ma thuật mà tôi chưa biết); –