2012-06-19 99 views
8

Tôi có một danh sách các đối tượng:Tạo danh sách các đối tượng thuộc tính trong python

[Object_1, Object_2, Object_3] 

Mỗi đối tượng có một thuộc tính: Thời gian:

Object_1.time = 20 
Object_2.time = 30 
Object_3.time = 40 

Tôi muốn tạo ra một danh sách các thời điểm thuộc tính:

[20, 30, 40] 

Cách hiệu quả nhất để có được kết quả này là gì? Nó không thể để lặp qua danh sách đối tượng, đúng ?:

items = [] 
for item in objects: 
    items.append(item.time) 
+0

'hiệu quả' nằm trong con mắt của người xem ... –

+1

@Pyson: Không, không "hiệu quả" được đo bằng độ phức tạp, thời gian tính toán, các dòng mã và/hoặc sử dụng bộ nhớ. – Junuxx

+4

@Junuxx: hầu hết mọi người không kiểm tra từng và từng trường hợp hiểu và so với vòng lặp để xem ít chu kỳ CPU hơn. Nếu bạn đang sử dụng Python, nó có lẽ là về dễ dàng để viết và đọc - không phải tốc độ tuyệt đối. Những gì bạn đã nêu ở đó, thời gian tính toán, các dòng mã và/hoặc sử dụng bộ nhớ, có thể hoàn toàn mâu thuẫn với nhau. Tăng gấp đôi mã có thể nhanh hơn và sử dụng ít bộ nhớ hơn, nhưng mất nhiều thời gian hơn để đọc và viết với tư cách là một lập trình viên. Đó là nhiều hơn * hiệu quả *? Nhanh hơn để thực thi hoặc nhanh hơn để viết bằng Python? Đây là quan điểm của tôi. –

Trả lời

23

Danh sách hiểu là những gì bạn đang sau:

list_of_objects = [Object_1, Object_2, Object_3] 
[x.time for x in list_of_objects] 
+0

Lưu ý rằng điều này hiệu quả như mã OP. – Marcin

+0

@Marcin: Trên thực tế, nó không được đảm bảo ở bất cứ nơi nào mà việc hiểu danh sách đều bằng nhau, nhiều hơn hoặc kém hiệu quả hơn so với danh sách tương đương. Chắc chắn, bạn có thể tìm ra câu trả lời bằng cách đọc mã CPython (hoặc các chuỗi danh sách gửi thư từ khi danh sách đã được đề xuất), nhưng bạn có thể giả định rằng sẽ áp dụng cho, nói, PyPy? Vì vậy, một điều tốt hơn để nói là không có lý do chính đáng để tin rằng điều này sẽ hiệu quả hơn. – abarnert

+4

Cái gì? Có, có. Một vòng lặp danh sách hiểu được thực hiện C-side, nhanh hơn đáng kể so với một vòng lặp Python.Bất kỳ việc thực hiện nào sẽ nhanh hơn vì việc hiểu danh sách là một điều ít biểu cảm hơn và do đó có thể được tối ưu hóa hiệu quả hơn. –

2

Làm thế nào về:

items=[item.time for item in objects] 
2
from operator import attrgetter 
items = map(attrgetter('time'), objects) 
+1

Lưu ý rằng bản đồ trả về trình tạo, không phải danh sách trong 3.x, và đó là một danh sách hiểu là dễ đọc hơn nhiều (và có lẽ nhanh hơn) cho một cái gì đó như thế này. –

+2

@Lattyware: +1. Và nếu bạn thực sự _want_ một máy phát điện, bạn có thể sử dụng một biểu thức máy phát điện cũng dễ dàng như một danh sách hiểu. – abarnert

2

Nhanh nhất (và dễ hiểu nhất) là với một danh sách hiểu.

Xem thời gian:

import timeit 
import random 
c=10000 

class SomeObj: 
    def __init__(self, i): 
     self.attr=i 

def loopCR(): 
    l=[] 
    for i in range(c): 
     l.append(SomeObj(random.random())) 

    return l 

def compCR(): 
    return [SomeObj(random.random()) for i in range(c)] 

def loopAc(): 
    lAttr=[] 
    for e in l: 
     lAttr.append(e.attr) 

    return lAttr 

def compAc(): 
    return [e.attr for e in l]    

t1=timeit.Timer(loopCR).timeit(10) 
t2=timeit.Timer(compCR).timeit(10) 
print "loop create:", t1,"secs" 
print "comprehension create:", t2,"secs" 
print 'Faster of those is', 100.0*abs(t1-t2)/max(t1,t2), '% faster' 
print 

l=compCR() 

t1=timeit.Timer(loopAc).timeit(10) 
t2=timeit.Timer(compAc).timeit(10) 
print "loop access:", t1,"secs" 
print "comprehension access:", t2,"secs" 
print 'Faster of those is', 100.0*abs(t1-t2)/max(t1,t2), '% faster' 

Prints:

loop create: 0.103852987289 secs 
comprehension create: 0.0848100185394 secs 
Faster of those is 18.3364670069 % faster 

loop access: 0.0206878185272 secs 
comprehension access: 0.00913000106812 secs 
Faster of those is 55.8677438315 % faster 

Vì vậy, danh sách hiểu là cả hai nhanh hơn để viết và nhanh hơn để thực thi.

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