2009-12-22 36 views
6

tôi có một danh sách mà trông giống như sauCách lấy giá trị trên một chỉ mục nhất định, trong danh sách python?

List = [q1,a1,q2,a2,q3,a3] 

tôi cần những mã cuối cùng là một cái gì đó như thế này

dictionary = {q1:a1,q2:a2,q3:a3} 

nếu duy nhất tôi có thể nhận được giá trị tại một số ví dụ Danh sách một số [0] Tôi có thể làm được điều này, có cách nào tôi có thể làm được không?

Trả lời

11

Từ điển Python có thể được xây dựng bằng cách sử dụng lớp dict, được cung cấp một bộ dữ liệu có thể lặp lại. Chúng ta có thể sử dụng kết hợp này với nội trang range để tạo ra một bộ sưu tập các bộ (như mọi mục, từng mục) và chuyển nó đến dict, sao cho các giá trị tự tổ chức thành các cặp khóa/giá trị trong kết quả cuối cùng:

dictionary = dict([(List[i], List[i+1]) for i in range(0, len(List), 2)]) 
+2

Bạn có thể loại bỏ '[]' s để thay đổi danh sách hiểu thành máy phát để đạt hiệu quả cao hơn: 'dict ((Danh sách [i], Danh sách [i + 1]) cho i trong phạm vi (0 , len (List), 2)) 'Bằng cách đó, nó sẽ không tạo ra một danh sách chỉ sau đó vứt nó đi sau khi nó được chuyển đổi thành một dict. –

+0

Bạn của tôi là một người tiết kiệm cuộc sống, Chúa ban phước cho bạn. Bây giờ tôi đã làm việc này trong hai giờ –

+0

OK, [] điều tôi đã để lại trước tiên cho khả năng tương thích py2.3, * và * cũng thực tế là tôi đã nghe chính xác - đối với các bộ sưu tập rất nhỏ, việc xây dựng danh sách là nhanh hơn chi phí xây dựng máy phát điện. Tôi có thể hỏi đồng nghiệp của tôi để biết thêm chi tiết về vấn đề này nhưng nó có ý nghĩa. – zzzeek

11

sử dụng ký hiệu lát mở rộng:

dictionary = dict(zip(List[0::2], List[1::2])) 
3

Câu trả lời phạm vi dựa trên là đơn giản, nhưng có cách tiếp cận khác có thể sử dụng các itertools gói:

from itertools import izip 
dictionary = dict(izip(*[iter(List)] * 2)) 

Breaking này xuống (chỉnh sửa: thử nghiệm thời gian này):

# Create instance of iterator wrapped around List 
# which will consume items one at a time when called. 
iter(List) 

# Put reference to iterator into list and duplicate it so 
# there are two references to the *same* iterator. 
[iter(List)] * 2 

# Pass each item in the list as a separate argument to the 
# izip() function. This uses the special * syntax that takes 
# a sequence and spreads it across a number of positional arguments. 
izip(* [iter(List)] * 2) 

# Use regular dict() constructor, same as in the answer by zzzeeek 
dict(izip(* [iter(List)] * 2)) 

Sửa: nhiều nhờ vào đôi mắt sắc nét Chris Lutz' cho việc sửa chữa gấp đôi.

+0

Nghịch trong hai dòng cuối cùng: Không có kết thúc '] ' –

+0

Sửa lỗi typo được chỉ ra bởi Chris (thanks!) –

+0

Bây giờ bạn đặt nó vào sai chỗ. 'iter (List) * 2' không phải là hợp lệ. –

0

Bạn đã đề cập trong nhận xét rằng bạn có mục nhập trùng lặp. Chúng ta có thể làm việc với điều này. Hãy phương pháp ưa thích của bạn tạo ra danh sách các hàng, và mở rộng nó thành một vòng lặp for:

from itertools import izip 

dictionary = {} 
for k, v in izip(List[::2], List[1::2]): 
    if k not in dictionary: 
     dictionary[k] = set() 
    dictionary[k].add(v) 

Hoặc chúng ta có thể sử dụng collections.defaultdict vì vậy chúng tôi không cần phải kiểm tra xem một chìa khóa đã được khởi tạo:

from itertools import izip 
from collections import defaultdict 

dictionary = defaultdict(set) 
for k, v in izip(List[::2], List[1::2]): 
    dictionary[k].add(v) 

Chúng tôi sẽ kết thúc bằng một từ điển có tất cả các khóa được đặt và các bộ chứa các giá trị. Điều này vẫn có thể không thích hợp, bởi vì bộ, như từ điển, không thể giữ bản sao, vì vậy nếu bạn cần một khóa duy nhất để giữ hai giá trị giống nhau, bạn sẽ cần phải thay đổi nó thành một bộ hoặc danh sách. Nhưng điều này sẽ giúp bạn bắt đầu.

2
d = {} 
for i in range(0, len(List), 2): 
    d[List[i]] = List[i+1] 
+0

Thats phổ biến những gì tôi đang suy nghĩ, điều đơn giản nhất và tốt nhất. :) –

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