2014-01-28 76 views
0

我有一個列表來自我使用非常原始的正則表達式分析過的文本文件。我想重新組織一個更簡單的列表,其中只包含緊跟着日期的文件。我試過使用len()循環列表,但那隻會提取文件而不是下一個條目。提前謝謝了。從列表中創建元組或新列表

此:

2014-01-28 

part002.csv.gz 

2014-01-28 

part001.csv.gz 

2014-01-28 

2014-01-28 

2014-01-27 

2014-01-27 

2014-01-26 

2014-01-26 

2014-01-25 

part002.csv.gz 

2014-01-25 

變爲這樣:

part002.csv.gz 

2014-01-28 

part001.csv.gz 

2014-01-28 

part002.csv.gz 

2014-01-25 

回答

0

商店在每行前行,那麼你總是有它,當你需要它

previous_line = None 
newlist = [] 
for line in lines: 
    if isdate(line): 
     newlist.append(previous_line) 
    previous_line = line 

定義isdate

import datetime 
def isdate(s): 
    try: 
     datetime.datetime.strptime(s, '%Y-%m-%d') 
    except: 
     return False 
    else: 
     return True 
0

工作通過它:

s = """ 
#that long string, snipped 
""" 

li = [x for x in s.splitlines() if x] 

li 
Out[3]: 
['2014-01-28', 
'part002.csv.gz', 
'2014-01-28', 
'part001.csv.gz', 
'2014-01-28', 
'2014-01-28', 
'2014-01-27', 
'2014-01-27', 
'2014-01-26', 
'2014-01-26', 
'2014-01-25', 
'part002.csv.gz', 
'2014-01-25'] 

[tup for tup in zip(li,li[1:]) if 'csv' in tup[0]] #shown for dicactic purposes, gen expression used below 
Out[7]: 
[('part002.csv.gz', '2014-01-28'), 
('part001.csv.gz', '2014-01-28'), 
('part002.csv.gz', '2014-01-25')] 

實際的答案:

from itertools import chain 

list(chain.from_iterable(tup for tup in zip(li,li[1:]) if 'csv' in tup[0])) 
Out[9]: 
['part002.csv.gz', 
'2014-01-28', 
'part001.csv.gz', 
'2014-01-28', 
'part002.csv.gz', 
'2014-01-25'] 

本質:用自身zip(在Python 2,使用izip)名單一起,一個指數上漲。迭代成對的元組,過濾出那些沒有類似文件的字符串的元素。最後,使用itertools.chain將這些元組展平成一個列表以實現您想要的輸出。

+1

聖#$%^,這是不真實的.....你是男人。你想我女朋友的電話號碼嗎?認真。 –

1

您可以使用列表理解:

filtered = [e for i, e in enumerate(l) if not isDate(e) or (i > 0 and not isDate(l[i-1]))] 

完整的示例:

l = ['2014-01-28', 'part002.csv.gz', '2014-01-28', 'part001.csv.gz', '2014-01-28', '2014-01-28', '2014-01-27', 'part002.csv.gz', '2014-01-25'] 

def isDate (s): 
    return '.' not in s 

filtered = [e for i, e in enumerate(l) if not isDate(e) or (i > 0 and not isDate(l[i-1]))] 

print (filtered) 

解釋:

l是我們最初的名單。

isDate需要一個字符串,並測試它是否是一個日期(在我的簡單示例中,它只是檢查它不包含句點,爲了更好的結果使用正則表達式或strptime)。枚舉一個列表(或任何可迭代的,我現在將堅持單詞list,只是爲了不太技術)。它返回一個元組列表;每個元組包含傳遞給枚舉的索引和元素。例如enumerate (['a', None, 3])使得[(0,'a'),(1,None),(2,3)]

i, e =解包元組,分配索引i和元件到e

列表理解是這樣工作的(簡單化):[x for x in somewhere if cond(x)]返回符合條件cond(x)的所有somewhere元素的列表。

在我們的例子中,我們只添加元素,我們的過濾名單,如果他們沒有時間(而不是水果)not isDate(e)或者如果他們在開始時沒有i > 0,並在同一時間他們的前身是不是日期not isDate(l[i-1])(即是,一個文件)。

僞代碼:

Take list `l` 
Let our filtered list be an empty list 
For each item in `l` do 
    let `i` be the index of the item 
    let `e` be the item itself 

    if `e` is not a Date 
     or if `i` > 0 (i.e. it is not the first item) 
     and at the sametime the preceding item is a File 
     then and only then add `e` to our filtered list. 
+0

我會用一些解釋擴展我的答案。 – Hyperboreus

+0

@ChaseCB我加了一些解釋。 – Hyperboreus

+0

讚美jah感謝 –