2015-10-07 27 views
1

我有一個遞歸構建的函數(該函數在具有嵌套分區的表的SQL查詢中查找所需的組件部分)。該表看起來是這樣的,如果有2個分區等級(在這種情況下,的某些地方和themonth):如何有效地改變未知深度列表中最右邊的值?

[[['theyear', '>=', 2014], ['OR'], ['theyear', '==', 2014, 'AND', [['themonth', '>=', 8], ['OR'], ['themonth', '==', 8, 'AND', False]]]], [['theyear', '<=', 2015], ['OR'], ['theyear', '==', 2015, 'AND', [['themonth', '<=', 9], ['OR'], ['themonth', '==', 9, 'AND', False]]]]] 

我希望做的是簡化

['themonth', '>=', 8], ['OR'], ['themonth', '==', 8, 'AND', False] 

得到的只是:

['themonth', '==', 8] 

但是,嵌套列表可以是任意深度的(例如,一個表可以按'theyear','themonth','theday','thehour'分區)。我知道在這個例子中深度= 2,但我很努力地想出如何自動改變mylist [0] [ - 1] [ - 1] ...的值並改變mylist [0] [ - 1] [-1] [ - 1] [ - 1]如果depth = 4。

更簡單的方法來這樣說,是,如果我有

a = [3, [4, [5]]] 

我知道深度爲3,我不能只用一個while循環基本上做

b = a[-1] 
b = b[-1] 
b = [6] 
>>> a 
[3, [4, [5]]] 

如何我可以定義一個函數來改變最右邊的值嗎?

回答

1
def changeLast(nested, new): 
    last = nested[-1] 
    if isinstance(last, list): 
     changeLast(last, new) 
    else: 
     nested[-1] = new 

a = [3, [4, [5]]] 
changeLast(a, 6) 
print(a) 

[3, [4, [6]]] 

我沒有做任何錯誤檢查。特別是,我不知道你會如何處理一個空的列表。

0

您需要循環或遞歸執行。然後爲每個級別檢查項目是否與isinstance()列表。如果它不是你找到最深的列表。

下面是一個迭代的方法:

def get_rightmost(l): 
    while True: 
    try: 
     # get last item of current list 
     item = l[-1] 
    except IndexError: 
     # empty list, return it 
     return l 
    # check if item is a list 
    if isinstance(item, list): 
     # continue with the list in the last item 
     l = item 
    else: 
     # return the current list 
     return l 

要改變右值,設置返回列表的最後一個元素:

rightmost_list = get_rightmost(your_list) 
rightmost_list[-1] = new_value # might fail with IndexError if list is empty. 
# So add a try-except block if you can't be sure the lists are never empty 
+1

我應該添加警告:您需要確保您的輸入不包含自引用。 'l = []; l.append(升); get_rightmost(l)'不會終止,因爲深度是無限的。在你的情況下,這可能不會發生,但如果有人使用這個未經檢查的用戶輸入:你已被警告:-) – cg909