2009-10-24 48 views
42

Gần đây tôi đã gặp phải một tình huống trong đó nếu một tập hợp chỉ chứa một phần tử duy nhất, tôi muốn làm điều gì đó với phần tử đó. Để có được yếu tố này, tôi đã giải quyết theo cách này:Làm thế nào để trích xuất các thành viên từ bộ đơn thành viên trong python?

element = list(myset)[0] 

Nhưng điều này không thỏa mãn vì nó tạo ra một danh sách không cần thiết. Nó cũng có thể được thực hiện với lặp lại, nhưng lặp lại dường như không tự nhiên là tốt, vì chỉ có một phần tử duy nhất. Tôi thiếu một cái gì đó đơn giản?

Trả lời

62

công việc giải nén tuple.

(element,) = myset 

(Bằng cách này, python-dev đã khám phá nhưng bác bỏ việc bổ sung các myset.get() để trở về một yếu tố tùy ý từ một tập. Discussion here, Guido van Rossum trả lời 12.)

yêu thích cá nhân của tôi để có được yếu tố tùy ý là (khi bạn có một số lượng không rõ, nhưng cũng làm việc nếu bạn chỉ có một):

element = next(iter(myset)) ¹ 

: bằng Python 2.5 và befor e, bạn phải sử dụng iter(myset).next()

+6

Very nice! Tôi thích rằng điều này thất bại nếu số lượng các yếu tố không phải là 1. –

+0

@Laurence: Đó là một quan sát tốt. Bắt lỗi sớm, phải không? – u0b34a0f6ae

+2

Hoặc, nếu bạn muốn giả vờ Python có một toán tử thích hợp cho công việc (đồng nghiệp của bạn sẽ ghét bạn): 'element, = myset' – rdb

2

bạn có thể sử dụng element = tuple(myset)[0] đó là hiệu quả hơn một chút, hoặc, bạn có thể làm điều gì đó như

element = iter(myset).next() 

Tôi đoán xây dựng một iterator là hiệu quả hơn so với việc xây dựng một tuple/danh sách .

+0

Tại sao bạn đoán việc xây dựng một trình lặp có hiệu quả hơn? –

+0

may mắn thay, tôi chỉ cho bạn phản hồi của Alex :) –

17

giữa thực hiện một tuple và làm cho một iterator, nó gần như là một rửa, nhưng chiến thắng lặp bởi một mũi ...:

$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]' 
1000000 loops, best of 3: 0.465 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]' 
1000000 loops, best of 3: 0.465 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))' 
1000000 loops, best of 3: 0.456 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))' 
1000000 loops, best of 3: 0.456 usec per loop 

Không chắc lý do tại sao tất cả các câu trả lời được bằng cách sử dụng cú pháp cũ iter(x).next() chứ không phải là mới next(iter(x)), mà có vẻ thích hợp hơn với tôi (và cũng hoạt động trong Python 3.1).

Tuy nhiên, chiến thắng giải nén tay xuống trên cả hai:

$ python2.6 -mtimeit -s'x=set([1])' 'a,=x' 
10000000 loops, best of 3: 0.174 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a,=x' 
10000000 loops, best of 3: 0.174 usec per loop 

Điều này tất nhiên là dành cho bộ đơn hàng (nơi các hình thức thứ hai, như những người khác đã đề cập, có lợi thế là thất bại nhanh chóng nếu các thiết lập bạn "biết" chỉ có một mục thực sự có một số). Đối với bộ với tùy mục N> 1, tuple chậm lại, iter không:

$ python2.6 -mtimeit -s'x=set(range(99))' 'a=next(iter(x))' 
1000000 loops, best of 3: 0.417 usec per loop 
$ python2.6 -mtimeit -s'x=set(range(99))' 'a=tuple(x)[0]' 
100000 loops, best of 3: 3.12 usec per loop 

Vì vậy, giải nén đối với trường hợp singleton, và next(iter(x)) đối với trường hợp chung, dường như tốt nhất.

+0

Tại sao cú pháp Python2.x? Tôi chỉ làm lập trình thực sự ở đó, và 'python' là Python 2.5 trên hệ thống của tôi, và do đó những gì xuất hiện khi tôi nhấn keybinding để mở một giao diện điều khiển python. – u0b34a0f6ae

+0

2.6 là hoàn toàn có thể sử dụng cho "lập trình thực" và phong phú hơn 2,5; lý do duy nhất để gắn bó với 2.5 là nếu môi trường bên ngoài của bạn hạn chế bạn (App Engine, Civilization 4, v.v.). tiếp theo (x) và x.next() cả hai làm việc trong 2.6, nhưng tiếp theo (x) là tốt hơn (cho phép bạn chỉ định một giá trị mặc định hơn là bắt ngoại lệ StopIteration, đòi hỏi một ký tự ít hơn ;-). –

+0

@ Alex: Không cần phải thuyết phục tôi, tôi sẽ sử dụng khá nhiều python 2.6. Tôi sử dụng debian, debian vẫn chưa hoàn thành việc chuyển sang Python 2.6! (Pyhthon 2.6 có sẵn nhưng không có thư viện phần thứ ba nào.) – u0b34a0f6ae

11

Tôi cho là kaizer.se's answer thật tuyệt. Nhưng nếu tập hợp của bạn có thể chứa nhiều phần tử và bạn muốn phần tử không phải tùy ý, bạn có thể muốn sử dụng min hoặc max. Ví dụ .:

element = min(myset) 

hay:

element = max(myset) 

(Không sử dụng sorted, bởi vì nó có chi phí không cần thiết cho việc sử dụng này.)

2

Tôi đề nghị:

element = myset.pop() 
+0

Điều này có thể hoạt động đối với một số trường hợp, nhưng nó làm thay đổi tập hợp. – recursive

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