2012-04-12 36 views
29

Tôi có câu hỏi về từ điển mà tôi muốn thực hiện. Mục tiêu của tôi là có nhiều khóa cho một giá trị, như sau:Làm cách nào để tạo từ điển có nhiều khóa cho một giá trị?

dictionary = {('a', 'b'): 1, ('c', 'd'): 2} 
assert dictionary['a'] == 1 
assert dictionary['b'] == 1 

Bất kỳ ý tưởng nào?

+3

Bạn có nghĩa là bạn muốn truy cập mục nhập đầu tiên với _either_ ''a'' hoặc'' b''? Giống như 'dictionary ['a']' và 'dictionary ['b']' cả hai đều trả về '1'? –

+0

Cũng giống như bạn nói, từ điển ['a'] = 1 và từ điển ['b'] = 1. – GiannisIordanou

+0

@evil_inside, ah, nếu đó là những gì bạn muốn, tại sao bạn không chỉ gán 1 cho cả hai khóa? – senderle

Trả lời

-1

Mã của bạn chỉ hoạt động:

In [1]: mydict ={('a','b'):1,('c','d'):2} 

In [2]: mydict 
Out[2]: {('a', 'b'): 1, ('c', 'd'): 2} 

In [3]: mydict['a', 'b'] 
Out[3]: 1 

In [4]: mydict[('a', 'b')] 
Out[4]: 1 

Lưu ý rằng đoạn mã trên được thực hiện bằng Python 2.7.8.

+0

Loại công việc: >>> mydict ['a '] Traceback (cuộc gọi gần đây nhất): Tệp "", dòng 1, trong Lỗi chính:' a ' – JosephSlote

+6

Không, cách này không hoạt động. Mã của anh ta sử dụng tuple ('a', 'b') làm khóa để lưu trữ giá trị 1, không phải chuỗi 'a' và 'b' là các khóa riêng biệt. – sage88

+0

@ sage88 Đã thử 'mydict [('a', 'b')] trong trình bao bằng Python 2.7.8 và nó hoạt động. Câu trả lời được chỉnh sửa và cập nhật để tránh bất kỳ sự hiểu lầm nào. Vui lòng xem xét lại phiếu bầu của bạn. –

21

Tôi đoán bạn có ý nghĩa này:

class Value: 
    def __init__(self, v=None): 
     self.v = v 

v1 = Value(1) 
v2 = Value(2) 

d = {'a': v1, 'b': v1, 'c': v2, 'd': v2} 
d['a'].v += 1 

d['b'].v == 2 # True 
  • chuỗi và số của Python là bất biến đối tượng,
  • Vì vậy, nếu bạn muốn d['a']d['b'] để trỏ đến cùng giá trị rằng " cập nhật "khi thay đổi, hãy đặt giá trị tham chiếu đến đối tượng có thể thay đổi (lớp do người dùng xác định như trên hoặc dict, list, set).
  • Sau đó, khi bạn sửa đổi đối tượng tại d['a'], d['b'] thay đổi cùng một lúc vì cả hai đều trỏ đến cùng một đối tượng.
+0

Bạn không cần phải sử dụng một đối tượng bất biến, chỉ cần gán giá trị bằng cách sử dụng cùng một biến (tham chiếu đến đối tượng) và bạn sẽ nhận được kết quả tương tự cho cả đối tượng có thể thay đổi và không thay đổi được e.g 'num = 2' và không phải trực tiếp đối tượng (' num' là biến và '2' là đối tượng). Bạn có thể kiểm tra nó bằng cách sử dụng từ khóa 'is', như sau:' if d ['a'] là d ['b']: '. nếu cả hai khóa trỏ đến cùng một đối tượng thì biểu thức sẽ là 'True' – Yomi

2

Ví dụ của bạn tạo nhiều cặp khóa: giá trị nếu sử dụng fromkeys. Nếu bạn không muốn điều này, bạn có thể sử dụng một khóa và tạo bí danh cho khóa. Ví dụ nếu bạn đang sử dụng một bản đồ đăng ký, khóa của bạn có thể là địa chỉ đăng ký và bí danh có thể là tên đăng ký. Bằng cách đó bạn có thể thực hiện các hoạt động đọc/ghi trên thanh ghi chính xác.

>>> mydict = {} 
>>> mydict[(1,2)] = [30, 20] 
>>> alias1 = (1,2) 
>>> print mydict[alias1] 
[30, 20] 
>>> mydict[(1,3)] = [30, 30] 
>>> print mydict 
{(1, 2): [30, 20], (1, 3): [30, 30]} 
>>> alias1 in mydict 
True 
3

Nếu bạn sắp thêm từ điển này thường xuyên, bạn muốn tham gia lớp học, cách tương tự như câu trả lời của @ Latty trong câu hỏi SO 2d-dictionary-with-many-keys-that-will-return-the-same-value này.

Tuy nhiên, nếu bạn có từ điển tĩnh và bạn chỉ cần giá trị truy cập bằng nhiều khóa thì bạn có thể sử dụng hai từ điển đơn giản. Một để lưu trữ các hiệp hội trọng điểm bí danh và một để lưu trữ dữ liệu thực tế của bạn:

alias = { 
    'a': 'id1', 
    'b': 'id1', 
    'c': 'id2', 
    'd': 'id2' 
} 

dict = { 
    'id1': 1, 
    'id2': 2 
} 

dict[alias['a']] 

Nếu bạn cần thêm vào từ điển bạn có thể viết một hàm như thế này cho sử dụng cả các từ điển:

def add(key, id, value=None) 
    if id in dict: 
     if key in alias: 
      # Do nothing 
      pass 
     else: 
      alias[key] = id 
    else: 
     dict[id] = value 
     alias[key] = id 

add('e', 'id2') 
add('f', 'id3', 3) 

Trong khi công trình này, tôi nghĩ cuối cùng nếu bạn muốn làm một cái gì đó như thế này viết cấu trúc dữ liệu của riêng bạn có lẽ là con đường để đi, mặc dù nó có thể sử dụng một cấu trúc tương tự.

0

Thật đơn giản. Điều đầu tiên bạn phải hiểu thiết kế của trình thông dịch Python. Nó không cấp phát bộ nhớ cho tất cả các biến cơ bản nếu có hai hoặc nhiều biến có cùng giá trị nó chỉ ánh xạ tới giá trị đó.

chúng ta hãy đi đến mã ví dụ,

In [6]: a = 10 

In [7]: id(a) 
Out[7]: 10914656 

In [8]: b = 10 

In [9]: id(b) 
Out[9]: 10914656 

In [10]: c = 11 

In [11]: id(c) 
Out[11]: 10914688 

In [12]: d = 21 

In [13]: id(d) 
Out[13]: 10915008 

In [14]: e = 11 

In [15]: id(e) 
Out[15]: 10914688 

In [16]: e = 21 

In [17]: id(e) 
Out[17]: 10915008 

In [18]: e is d 
Out[18]: True 
In [19]: e = 30 

In [20]: id(e) 
Out[20]: 10915296 

Từ đầu ra ở trên, các biến a và cổ phiếu b bộ nhớ tương tự, c và d có bộ nhớ khác nhau khi tôi tạo ra một biến e mới và lưu trữ một giá trị (11) đã có mặt trong biến c sao cho nó được ánh xạ tới vị trí bộ nhớ đó và không tạo ra bộ nhớ mới khi tôi thay đổi giá trị hiện tại trong biến e đến 21 đã có trong biến d vì vậy bây giờ biến d và e chia sẻ cùng một vị trí bộ nhớ. Cuối cùng, tôi thay đổi giá trị trong biến e thành 30 mà không được lưu trữ trong bất kỳ biến nào khác để nó tạo ra một bộ nhớ mới cho e.

vì vậy bất kỳ biến nào có cùng giá trị chia sẻ bộ nhớ.

Not for list and dictionary objects

hãy đến với câu hỏi của bạn.

khi nhiều khóa có cùng giá trị thì tất cả chia sẻ cùng một bộ nhớ để điều bạn mong đợi đã có trong python.

bạn chỉ có thể sử dụng nó như thế này

In [49]: dictionary = { 
    ...:  'k1':1, 
    ...:  'k2':1, 
    ...:  'k3':2, 
    ...:  'k4':2} 
    ...:  
    ...:  

In [50]: id(dictionary['k1']) 
Out[50]: 10914368 

In [51]: id(dictionary['k2']) 
Out[51]: 10914368 

In [52]: id(dictionary['k3']) 
Out[52]: 10914400 

In [53]: id(dictionary['k4']) 
Out[53]: 10914400 

Từ sản lượng trên, k1 chủ chốt và k2 ánh xạ tới cùng một địa chỉ có nghĩa là giá trị một lưu trữ một lần duy nhất trong bộ nhớ đó là nhiều chìa khóa từ điển giá trị duy nhất đây là điều bạn muốn. : P

Các vấn đề liên quan