2017-08-25 86 views
0

我想找到類中第二個屬性的對象,使第一個屬性具有特定的值。根據該對象的第二個屬性訪問python對象的屬性

Class Day(object): 
    def __init__(self, a_datetime_date): 
     self.date = a_datetime_date 
     self.colour = None 

我現在實例一大堆對象在一個循環:

for x in a_list_of_dates: 
    some_day = Day(x) 
    some_day.colour = 'Red' # or some other values depending on the details 

是相當新的對象,我只是救了他們的字典。 {'1': <__main__.Day object at 0x7f9a444cacd0>, '2': <__main__.Day object at 0x7f9a447cacd0>, etc}

現在有一個簡單的方法可以讓我檢索對應於日期範圍的colour?或者,也許,更簡單的一個日期?

我只能想辦法像sorted(dict.iteritems()),然後通過列表檢查day_object.date一個接一個。如果是我想要的日期,那麼使用day_object.colour來查找顏色。

的問題的答案可能有兩種形式:

  1. 一種更好的方式來存儲/訪問幾百對象(不是字典等)
  2. 一個查詢在字典中的對象的方式以獲得我感興趣的日子的顏色。

謝謝。

編輯:在簡化一個小問題時,我沒有使用類的動機。 「日」對象實際上有15個屬性和2個方法(不僅僅是colour)。所以@科爾的建議是好的,但沒有這麼多的屬性。這些對象用於計算各種事物:300天中有多少是休息時間?有多少天是半天?也許我被困在使用複雜的列表/字典和移動到完整的ORM之間?

+0

它幾乎聽起來像是你想要一個ORM。 –

回答

2

我認爲你可以使用bisectOrderedDict

import bisect 
from collections import OrderedDict 

def foo(date): 
    day = Day(date) 
    day.colour = 'Red' # or some other values depending on the details 
    return day 

container = OrderDict({date: foo(date) for date in sorted(date_list)}) 

keys = list(container.keys()) 

# find by range of dates 

start_index = bisect.bisect_left(keys, start_date) 
end_index = bisect.bisect(keys, end_date) 

for index in range(start_index, end_index); 
    print(container[keys[index]].colour) 

# find by a single date 

print(container[single_date].colour) 
0
  1. 你確定你不想要一個數組嗎?數據結構可以輕鬆處理幾百個對象,但在這裏使用數組更有意義。

  2. 我會用filter

filter(lambda day: min_date < day.date < max_date, array_of_dates)

注意,這是假設你有日期的數組。


寫在那之後的想法來找我:爲什麼不與對象廢除完全,只是有鍵爲DateTime對象,並作爲顏色值的字典?儘管如此,你仍然需要filter來獲得一個範圍(它應該比至少排序更快)。

+0

這是有道理的,重讀我的問題。請參閱上面的評論以獲取有關問題實際複雜性的更多詳細信息。 – Massagran

+0

我會跟@ stamaimer的解決方案去自己。有序的詞典似乎更合理。 – cole

0

也許你不應該在這裏使用一個類,如果你想要的是字典。有一個good video about this on youtube。與列表類相比,使用列表列表更容易。你甚至可以有一個字典,每個關鍵字都是日期,如果每個關鍵字都是唯一的話。

當你說你'把他們保存在字典'中是什麼意思?你把每個班的副本當作一個字典,每個都有一個數字鍵?這是浪費內存和CPU時間。

1

首先,列表是你想要做什麼更好的數據結構。除非這些鍵有一些在問題中不明顯的含義。

你可以做你想做的與列表理解(一旦一切都在一個列表)。

foo = list() 
for date in dates: 
    some_day = Day(date) 
    some_day.colour = 'Red' 
    foo.append(some_day) 

values = [x.colour for x in foo if date_1 <= x.date <= date_2] 
+0

這裏的代碼(https://gist.github.com/alphydan/bd3d5cf1b7b6acf3b76f818c73b5965f)更多的上下文。我簡化了這裏的密鑰以儘量保持簡單。那麼嵌套列表的列表將是另一種選擇? – Massagran

+0

不幸的是,還依賴於其他3個或4個屬性。我在這裏簡化了課程,但必須在這些日期之間,不是假期,不是半天,不是假期學習日,不是週末......然後找到「顏色」和數字當然等等原則是相同的,但取決於許多屬性。 – Massagran

1

我不知道你打算用這個做除了看顏色什麼。嘗試使用顏色散列字典;這將讓創建色彩和日之間的關係:在重新

from collections import defaultdict 
color_dict = defaultdict(list) 

for x in a_list_of_dates: 
    some_day = Day(x) 
    some_day.colour = 'Red' # Not sure how you're planning to make these assignments. 
    colour_dict['Red'].append(some_day) 

# Look up all Day objects colored Red 
colour_dict['Red'] 

:「要查詢的字典獲得的日子,我很感興趣的顏色對象的一種方式」 如果你想要去與當前詞典數據結構 - 我不會推薦:):

[day for day in dict_of_days.values if day.colour='Red'] 

但是你會發現,你的鑰匙沒有太大的意義或實用工具以這種形式,所以我'd建議將它存儲在列表中而不是字典中。一旦在列表中,你可以運行下面讓所有日子,是紅色:

[day for day in list_of_days if day.colour='Red'] 

替代解決方案

  1. 存儲你的數據在大熊貓數據幀http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html。通過這種方式,您可以以表格格式(即列= [日,顏色,IsHalfDay等])對數據進行切片和切塊。
  2. 對於快速輕量級的ORM解決方案,嘗試一對多(逐日顏色)或多對多(逐日)關係http://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html