2013-02-04 54 views
1

假設我有一個路徑,例如/resource/123/resourceb/b/someotherresource/。在這種情況下,someotherresource沒有資源ID。這個例子有3個資源,但我需要處理1-4個資源之間的任何地方。將數組組合到元組數組中 - 奇數長度

什麼是它拆分成[(a,b), (c,d), (e, None)]

例一pythonic的方法:

x = '/resource/123/resourceb/b/someotherresource/' 
xplit = x.split('/') 
>>> [ 'resource', '123', 'resourceb', 'b', 'someotherresource'] 
import magic 
# ideal result 
>>> [ ('resource', '123'), ('resourceb', 'b'), ('someotherresource', None)] 

我知道我能做到這一點的笨方法,但有一個簡單的方法來拆分&對的數組奇數長度?

+0

會適應[此答案](http://stackoverflow.com/questions/312443/how-do-you-split-a-列表中的大小不一的塊在Python中)來處理奇數會做伎倆,或者是你說的愚蠢的方式。 –

+0

@cms_mgr該問題的最佳答案是次優的,因爲它只能用於序列,而不是任意的迭代。 –

回答

2
In [24]: x 
Out[24]: '/resource/123/resourceb/b/someotherresource/' 

In [25]: s = x.strip('/').split('/') 

In [26]: zip(s[::2], s[1::2] + [None]) 
Out[26]: [('resource', '123'), ('resourceb', 'b'), ('someotherresource', None)] 
+1

+1我喜歡這一個。沒有附加條件,沒有依賴關係。沒有lambda。只需跨越切片和拉鍊。尼斯 – sehe

+0

這確實依賴's'作爲一個列表,而不是一個任意的可迭代,根據使用情況,這是一個小的次優。 (它也不能很好地擴展到不同規模的團體)。 –

2

使用itertools.izip_longest()iter魔法:

import itertools 
list(itertools.izip_longest(*[iter(xplit[1:])]*2)) 

我們開始在索引1,因爲領先/斜線讓你在一開始的空元素。

備選地,在開始和結束的斜線的條帶:

list(itertools.izip_longest(*[iter(x.strip('/').split('/'))]*2)) 

輸出:

>>> list(itertools.izip_longest(*[iter(x.strip('/').split('/'))]*2)) 
[('resource', '123'), ('resourceb', 'b'), ('someotherresource', None)] 

裹起來爲魔術方法:

import itertools 

def split_to_pairs(path): 
    path = path.strip('/').split('/') 
    return list(itertools.izip_longest(*[iter(path)]*2)) 
+0

你不需要'izip_longest'來獲得'None'嗎? – mgilson

+0

@mgilson:確實,旅行的疲憊讓我變得遲鈍! –

+0

我碰巧在吃零食的fudgesickle放慢了我;-) – mgilson

1

檢查出grouper()recipie from itertools

def grouper(n, iterable, fillvalue=None): 
    "Collect data into fixed-length chunks or blocks" 
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return zip_longest(*args, fillvalue=fillvalue) 

(在2.x中,zip_longest()izip_longest()