2012-08-16 65 views
1

假設我有一個列表,其中每個索引都是名稱或前一個名稱索引保留的房間列表。Python:將列表鏈接在一起

[["Bob"],["125A, "154B", "643A"],["142C", "192B"], ["653G"], 
["Carol"], ["95H", 123C"], ["David"], ["120G"]] 

因此,在這種情況下,Bob擁有客房:125A,154B,643A,152C,192B和653G預留等

如何構建一個功能,將使上述進入以下格式:

[["Bob", "125A, "154B", "643A", "142C", "192B", "653G"], ["Carol"... 

基本上將[名稱]與所有[客房預訂列表]連接在一起,直到下一個[名稱]實例。我有一個功能它接受一個列表,並返回True如果列表的名稱,False如果是預訂房間的列表,以便有效地我:

[True, False, False, False, True, False, True False]對上述名單,但不知道如果有的話,這對我有什麼幫助。假設列表包含名稱,它只有一個名稱。

+1

嘗試創建一個更連貫的數據結構。根據經驗,總是避免將不同類型或含義的元素存儲在同一個列表中。相反,請使用列表或字典列表。 – slezica 2012-08-16 07:44:56

+0

我會如果我能,但這是我給的東西,而不是我自己創造的東西lol – zhuyxn 2012-08-16 07:47:32

回答

1

給出的以下方法

def is_name(x): 
    return # if x is a name or not 

一個簡單且短解決方案是使用一個defaultdict


實施例:

from collections import defaultdict 

def do_it(source): 
    dd = defaultdict(lambda: []) 
    for item in sum(source, []): # just use your favourite flattening method here 
    if is_name(item): 
     name = item 
    else: 
     dd[name].append(item) 
    return [[k]+v for k,v in dd.items()] 

for s in do_it(l): 
    print s 

輸出:

[ '鮑勃', '125A', '154B', '643A', '142C', '192B', '653G']
[ '卡羅爾', '95H', '123C']
[ '大衛', '120G']


加成:

這其中使用了發電機懶惰

import itertools 

def do_it(source): 
    name, items = None, [] 
    for item in itertools.chain.from_iterable(source): 
    if is_name(item): 
     if name: 
     yield [name] + items 
     name, items = None, [] 
     name = item 
    else: 
     items.append(item) 
    yield [name] + items 
0

我會在此前言說我非常贊同@uʍopǝpısdn的建議。但是,如果你的設置將不讓改變它的一些原因,這似乎工作(雖然它不是漂亮):

# Original list 
l = [["Bob"],["125A", "154B", "643A"],["142C", "192B"], ["653G"], ["Carol"], ["95H", "123C"], ["David"], ["120G"]] 
# This is the result of your checking function 
mapper = [True, False, False, False, True, False, True, False] 

# Final list 
combined = [] 

# Generic counters 
# Position in arrays 
i = 0 
# Position in combined list 
k = 0 

# Loop through the main list until the end. 
# We don't use a for loop here because we want to be able to control the 
# position of i. 
while i < len(l): 
    # If the corresponding value is True, start building the list 
    if mapper[i]: 
    # This is an example of how the code gets messy quickly 
    combined.append([l[i][0]]) 
    i += 1 
    # Now that we've hit a name, loop until we hit another, adding the 
    # non-name information to the original list 
    while i < len(mapper) and not mapper[i]: 
     combined[k].append(l[i][0]) 
     i += 1 

    # increment the position in our combined list 
    k += 1 


print combined 
0

假設它接受一個列表,並根據列表中是否包含名稱返回真或假的函數或房間被稱爲containsName()...

def process(items): 
    results = [] 
    name_and_rooms = [] 
    for item in items: 
    if containsName(item): 
     if name_and_rooms: 
     results.append(name_and_rooms[:]) 
     name_and_rooms = [] 
     name_and_rooms.append(item[0]) 
    else: 
     name_and_rooms.extend(item) 
    if name_and_rooms: 
    results.append(name_and_rooms[:]) 
    return results 

這將打印出來的名字,即使有沒有房間的名單跟隨,如[[ '鮑勃'],[ '蘇珊']]。

此外,這不會合並重複名稱,例如[[ '鮑勃'],[ '123'],[ '鮑勃'],[ '456']]。如果這是需要的,那麼你需要將名稱轉換爲臨時字典,而每個房間列表都是值。然後在最後吐出字典的鍵值。但是,它本身並不會保留名稱的順序。如果你關心保存名字的順序,你可以有另一個包含名字順序的列表,並且在吐出字典中的值時使用它。

0

真的,你應該使用這個dict。這假定列表的順序不變(名稱總是在前)。

正如其他人建議你應該重新評估你的數據結構。

>>> from itertools import chain 
>>> li_combo = list(chain.from_iterable(lst)) 
>>> d = {} 
>>> for i in li_combo: 
... if is_name(i): 
...  k = i 
... if k not in d: 
...  d[k] = [] 
... else: 
...  d[k].append(i) 
... 
>>> final_list = [[k]+d[k] for k in d] 
>>> final_list 
[['Bob', '125A', '154B', '643A', '142C', '192B', '653G'], ['Carol', '95H', '123C'], ['David', '120G']] 
0

減少是你的答案。你的數據是這樣的:

l=[['Bob'], ['125A', '154B', '643A'], ['142C', '192B'], ['653G'], ['Carol'], ['95H', '123C'], ['David'], ['120G']] 

你說你已經有一個函數來確定一個元素是否是一個名字。這是我的一個:

import re 
def is_name(s): 
    return re.match("[A-z]+$",s) and True or False 

然後,使用減少,這是一個班輪:

reduce(lambda c, n: is_name(n[0]) and c+[n] or c[:-1]+[c[-1]+n], l, []) 

結果是:

[['Bob', '125A', '154B', '643A', '142C', '192B', '653G'], ['Carol', '95H', '123C'], ['David', '120G']] 
+0

其實,它很難讀... – sloth 2012-08-18 09:02:36

+0

什麼是難以閱讀?爲什麼? – Benedict 2012-08-19 13:51:57